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

* lib/generator.rb: should work with another thread. (more robust code)

[ruby-dev:28177]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9763 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ocean 2005-12-29 16:08:44 +00:00
parent 84dd697417
commit 0cb24bf1b9
2 changed files with 17 additions and 7 deletions

View file

@ -1,3 +1,8 @@
Fri Dec 30 01:04:52 2005 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>
* lib/generator.rb: should work with another thread. (more robust code)
[ruby-dev:28177]
Thu Dec 29 23:59:37 2005 Nobuyoshi Nakada <nobu@ruby-lang.org> Thu Dec 29 23:59:37 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
* eval.c (rb_gc_mark_threads): keep unmarked threads which won't wake * eval.c (rb_gc_mark_threads): keep unmarked threads which won't wake

View file

@ -73,14 +73,12 @@ class Generator
@queue = [] @queue = []
@loop_thread = Thread.new do @loop_thread = Thread.new do
Thread.stop Thread.stop
Thread.critical = true
begin begin
@block.call(self) # exception safe? @block.call(self) # exception safe?
rescue rescue
@main_thread.raise $! @main_thread.raise $!
ensure ensure
@main_thread.wakeup @main_thread.wakeup
Thread.critical = false
end end
end end
self self
@ -89,21 +87,28 @@ class Generator
# Yields an element to the generator. # Yields an element to the generator.
def yield(value) def yield(value)
if Thread.current != @loop_thread if Thread.current != @loop_thread
raise RuntimeError.new("Generator#yield must be called in Generator.new{|g| ... }") raise "should be called in Generator.new{|g| ... }"
end end
@queue << value
@main_thread.wakeup
Thread.stop
Thread.critical = true Thread.critical = true
begin
@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?
if @queue.empty? if @queue.empty?
if @main_thread
raise "should not be called in Generator.new{|g| ... }"
end
Thread.critical = true Thread.critical = true
@main_thread = Thread.current
begin begin
@main_thread = Thread.current
@loop_thread.wakeup @loop_thread.wakeup
Thread.stop Thread.stop
rescue ThreadError rescue ThreadError