# File lib/eventmachine.rb, line 149
  def self.run blk=nil, tail=nil, &block
    # Obsoleted the use_threads mechanism.
    # 25Nov06: Added the begin/ensure block. We need to be sure that release_machine
    # gets called even if an exception gets thrown within any of the user code
    # that the event loop runs. The best way to see this is to run a unit
    # test with two functions, each of which calls {EventMachine.run} and each of
    # which throws something inside of #run. Without the ensure, the second test
    # will start without release_machine being called and will immediately throw

    #
    if reactor_running? and @reactor_pid != Process.pid
      # Reactor was started in a different parent, meaning we have forked.
      # Clean up reactor state so a new reactor boots up in this child.
      stop_event_loop
      release_machine
      @reactor_running = false
    end

    tail and @tails.unshift(tail)

    if reactor_running?
      (b = blk || block) and b.call # next_tick(b)
    else
      @conns = {}
      @acceptors = {}
      @timers = {}
      @wrapped_exception = nil
      @next_tick_queue ||= []
      @tails ||= []
      begin
        @reactor_pid = Process.pid
        @reactor_running = true
        initialize_event_machine
        (b = blk || block) and add_timer(0, b)
        if @next_tick_queue && !@next_tick_queue.empty?
          add_timer(0) { signal_loopbreak }
        end
        @reactor_thread = Thread.current
        run_machine
      ensure
        until @tails.empty?
          @tails.pop.call
        end

        begin
          release_machine
        ensure
          if @threadpool
            @threadpool.each { |t| t.exit }
            @threadpool.each do |t|
              next unless t.alive?
              begin
                # Thread#kill! does not exist on 1.9 or rbx, and raises
                # NotImplemented on jruby
                t.kill!
              rescue NoMethodError, NotImplementedError
                t.kill
                # XXX t.join here?
              end
            end
            @threadqueue = nil
            @resultqueue = nil
            @threadpool = nil
            @all_threads_spawned = false
          end

          @next_tick_queue = []
        end
        @reactor_running = false
        @reactor_thread = nil
      end

      raise @wrapped_exception if @wrapped_exception
    end
  end