236: def self.run blk=nil, tail=nil, &block
237: @tails ||= []
238: tail and @tails.unshift(tail)
239:
240: if reactor_running?
241: (b = blk || block) and b.call
242: else
243: @conns = {}
244: @acceptors = {}
245: @timers = {}
246: @wrapped_exception = nil
247: @next_tick_queue ||= []
248: begin
249: @reactor_running = true
250: initialize_event_machine
251: (b = blk || block) and add_timer(0, b)
252: if @next_tick_queue && !@next_tick_queue.empty?
253: add_timer(0) { signal_loopbreak }
254: end
255: @reactor_thread = Thread.current
256: run_machine
257: ensure
258: until @tails.empty?
259: @tails.pop.call
260: end
261:
262: begin
263: release_machine
264: ensure
265: if @threadpool
266: @threadpool.each { |t| t.exit }
267: @threadpool.each do |t|
268: next unless t.alive?
269:
270: t.respond_to?(:kill!) ? t.kill! : t.kill
271: end
272: @threadqueue = nil
273: @resultqueue = nil
274: @threadpool = nil
275: end
276:
277: @next_tick_queue = nil
278: end
279: @reactor_running = false
280: @reactor_thread = nil
281: end
282:
283: raise @wrapped_exception if @wrapped_exception
284: end
285: end