diff --git a/spec/event_catcher_spec.rb b/spec/event_catcher_spec.rb index c23302f..f2a3cfa 100644 --- a/spec/event_catcher_spec.rb +++ b/spec/event_catcher_spec.rb @@ -4,21 +4,22 @@ describe EventCatcher do subject { EventCatcher.new } + let!(:latch) { Latch.new } + describe :wait_for do it %[should wake when an event is delivered] do - pending "this has a pretty awful race in it" th = Thread.new do subject.synchronize do logger.debug { "about to wait for created" } + latch.release subject.wait_for_created logger.debug { "woke up, created must have been delivered" } end true end - th.run - Thread.pass until th.status == 'sleep' + latch.await logger.debug { "th.status: #{th.status}" } diff --git a/spec/support/event_catcher.rb b/spec/support/event_catcher.rb index f559acd..0bbb566 100644 --- a/spec/support/event_catcher.rb +++ b/spec/support/event_catcher.rb @@ -64,15 +64,15 @@ def cond_#{name} # waits for an event group to not be empty (up to timeout sec) def wait_for_#{name}(timeout=5) - cond(:#{name}).wait(timeout) + wait_for(:#{name}, timeout) end - def wait_while_#{name} - cond(:#{name}).wait_while { yield __send__(:#{name}) } + def wait_while_#{name}(&blk) + wait_while(:#{name}, &blk) end - def wait_until_#{name} - cond(:#{name}).wait_until { yield __send__(:#{name}) } + def wait_until_#{name}(&blk) + wait_until(:#{name}, &blk) end EOS end diff --git a/spec/support/latch.rb b/spec/support/latch.rb new file mode 100644 index 0000000..d96d920 --- /dev/null +++ b/spec/support/latch.rb @@ -0,0 +1,23 @@ +# the much fabled 'latch' that tenderlove and nahi were on about + +class Latch + def initialize(count = 1) + @count = count + @mutex = Monitor.new + @cond = @mutex.new_cond + end + + def release + @mutex.synchronize { + @count -= 1 if @count > 0 + @cond.broadcast if @count.zero? + } + end + + def await + @mutex.synchronize { + @cond.wait_while { @count > 0 } + } + end +end +