From c0c75769b689b34be85e2b7e1b92016e7b67563e Mon Sep 17 00:00:00 2001 From: ocean Date: Fri, 30 Dec 2005 09:57:49 +0000 Subject: [PATCH] Sorry, reverted. Mutex is damn slow..... git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9774 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 ---- lib/generator.rb | 61 ++++++++++++++++++++++++------------------------ 2 files changed, 30 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index cbd37bb6e6..9f03661c77 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,3 @@ -Fri Dec 30 18:27:00 2005 Hirokazu Yamamoto - - * lib/generator.rb: uses Mutex instead of Thread.critical. - [ruby-dev:28184] - Fri Dec 30 18:22:42 2005 Nobuyoshi Nakada * gc.c (garbage_collect): mark objects refered from aborting threads. diff --git a/lib/generator.rb b/lib/generator.rb index 19f2385449..241987faba 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?