From 18e93b1d8d0b18e405b7094b5fc54d96e8aa456d Mon Sep 17 00:00:00 2001 From: ocean Date: Fri, 30 Dec 2005 09:57:49 +0000 Subject: Sorry, reverted. Mutex is damn slow..... git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@9774 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/generator.rb | 61 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 31 deletions(-) (limited to 'lib') diff --git a/lib/generator.rb b/lib/generator.rb index 19f238544..241987fab 100644 --- a/lib/generator.rb +++ b/lib/generator.rb @@ -23,7 +23,6 @@ # # See the respective classes for examples of usage. -require "thread" # # Generator converts an internal iterator (i.e. an Enumerable object) @@ -72,24 +71,17 @@ class Generator end @index = 0 @queue = [] - @mutex = Mutex.new - @main_cond = ConditionVariable.new - @loop_cond = ConditionVariable.new - entered = false @loop_thread = Thread.new do - @mutex.synchronize do - entered = true - @loop_cond.wait(@mutex) - begin - @block.call(self) - rescue - @main_thread.raise $! - ensure - @main_cond.signal - end + Thread.stop + begin + @block.call(self) + rescue + @main_thread.raise + ensure + @main_thread.wakeup end end - Thread.pass until entered && !@mutex.locked? + Thread.pass until @loop_thread.stop? self end @@ -98,26 +90,33 @@ class Generator if Thread.current != @loop_thread raise "should be called in Generator.new{|g| ... }" end - @queue << value - @main_cond.signal - @loop_cond.wait(@mutex) + Thread.critical = true + begin + @queue << value + @main_thread.wakeup + Thread.stop + ensure + Thread.critical = false + end self end # Returns true if the generator has reached the end. def end? - @mutex.synchronize do - if @queue.empty? && @loop_thread.alive? - if @main_thread - raise "should not be called in Generator.new{|g| ... }" - end - begin - @main_thread = Thread.current - @loop_cond.signal - @main_cond.wait(@mutex) - ensure - @main_thread = nil - end + if @queue.empty? + if @main_thread + raise "should not be called in Generator.new{|g| ... }" + end + Thread.critical = true + begin + @main_thread = Thread.current + @loop_thread.wakeup + Thread.stop + rescue ThreadError + # ignore + ensure + @main_thread = nil + Thread.critical = false end end @queue.empty? -- cgit