Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
EventMachine.crank
require 'thread'
module EventMachine
module Test
module Utils
module Cranking
# Stolen from MenTaLguYs Omnibus
class Waiter
def initialize
@lock = Mutex.new
@condition = ConditionVariable.new
@set = false
end
def wait
@lock.synchronize do
@condition.wait(@lock) unless @set
@set = false
end
self
end
def wakeup
@lock.synchronize do
@set = true
@condition.signal
end
self
end
end
def setup
raise 'EventMachine already running' if EM.reactor_running?
@em_waiter = Waiter.new
@th_waiter = Waiter.new
@cranking = true
@cranker = lambda {
@th_waiter.wakeup
@em_waiter.wait
EM.next_tick &@cranker if @cranking
}
@crank_thread = Thread.new { EM.run { EM.next_tick &@cranker } }
@th_waiter.wait
end
def teardown
@cranking = false
@em_waiter.wakeup # free reactor
EM.stop
@crank_thread.join
end
def crank!
@em_waiter.wakeup
@th_waiter.wait
end
end
end
end
end
BEGIN { require 'rubygems' if __FILE__ == $0 }
if __FILE__ == $0
require 'eventmachine'
require 'minitest/unit'
class TestEventMachineTestUtilsCranking < MiniTest::Unit::TestCase
Thread.abort_on_exception = true
include EventMachine::Test::Utils::Cranking
def test_crank_counter
count = 0
counter = lambda { count += 1; EM.next_tick &counter }
EM.next_tick &counter
1000.times { |n|
assert_equal n, count
crank!
}
end
end
MiniTest::Unit.autorun
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment