1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Sorry, reverted. Mutex is damn slow.....

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9774 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ocean 2005-12-30 09:57:49 +00:00
parent 2c1706fffb
commit c0c75769b6
2 changed files with 30 additions and 36 deletions

View file

@ -1,8 +1,3 @@
Fri Dec 30 18:27:00 2005 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>
* lib/generator.rb: uses Mutex instead of Thread.critical.
[ruby-dev:28184]
Fri Dec 30 18:22:42 2005 Nobuyoshi Nakada <nobu@ruby-lang.org> Fri Dec 30 18:22:42 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
* gc.c (garbage_collect): mark objects refered from aborting threads. * gc.c (garbage_collect): mark objects refered from aborting threads.

View file

@ -23,7 +23,6 @@
# #
# See the respective classes for examples of usage. # See the respective classes for examples of usage.
require "thread"
# #
# Generator converts an internal iterator (i.e. an Enumerable object) # Generator converts an internal iterator (i.e. an Enumerable object)
@ -72,24 +71,17 @@ class Generator
end end
@index = 0 @index = 0
@queue = [] @queue = []
@mutex = Mutex.new
@main_cond = ConditionVariable.new
@loop_cond = ConditionVariable.new
entered = false
@loop_thread = Thread.new do @loop_thread = Thread.new do
@mutex.synchronize do Thread.stop
entered = true begin
@loop_cond.wait(@mutex) @block.call(self)
begin rescue
@block.call(self) @main_thread.raise
rescue ensure
@main_thread.raise $! @main_thread.wakeup
ensure
@main_cond.signal
end
end end
end end
Thread.pass until entered && !@mutex.locked? Thread.pass until @loop_thread.stop?
self self
end end
@ -98,26 +90,33 @@ class Generator
if Thread.current != @loop_thread if Thread.current != @loop_thread
raise "should be called in Generator.new{|g| ... }" raise "should be called in Generator.new{|g| ... }"
end end
@queue << value Thread.critical = true
@main_cond.signal begin
@loop_cond.wait(@mutex) @queue << value
@main_thread.wakeup
Thread.stop
ensure
Thread.critical = false
end
self self
end end
# Returns true if the generator has reached the end. # Returns true if the generator has reached the end.
def end? def end?
@mutex.synchronize do if @queue.empty?
if @queue.empty? && @loop_thread.alive? if @main_thread
if @main_thread raise "should not be called in Generator.new{|g| ... }"
raise "should not be called in Generator.new{|g| ... }" end
end Thread.critical = true
begin begin
@main_thread = Thread.current @main_thread = Thread.current
@loop_cond.signal @loop_thread.wakeup
@main_cond.wait(@mutex) Thread.stop
ensure rescue ThreadError
@main_thread = nil # ignore
end ensure
@main_thread = nil
Thread.critical = false
end end
end end
@queue.empty? @queue.empty?