[#27919] 1.8.4 Preview2 検証 — "URABE Shyouhei aka. mput" <root@...>

卜部です。

33 messages 2005/12/01

[#27997] 1.8.4 documents? — "URABE Shyouhei aka. mput" <root@...>

卜部です。

22 messages 2005/12/12
[#28017] Re: 1.8.4 documents? — Koji Arai <jca02266@...> 2005/12/13

新井です。

[#28082] ruby_1_8 Segmentation fault on Cygwin — yanagi@...

柳田です。

13 messages 2005/12/21
[#28083] Re: ruby_1_8 Segmentation fault on Cygwin — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/12/21

山本です。

[#28140] ia64-hpux11.23/socket.sl: this executable file can't load extension libraries (LoadError) — Tanaka Akira <akr@...17n.org>

HP-UX で HP aC++/ANSI C を使って作った ruby で、openssl や drb のテストをすると、

34 messages 2005/12/27
[#28141] Re: ia64-hpux11.23/socket.sl: this executable file can't load extension libraries (LoadError) — WATANABE Tetsuya <Tetsuya.WATANABE@...> 2005/12/28

渡辺哲也です。

[#28142] Re: ia64-hpux11.23/socket.sl: this executable file can't load extension libraries (LoadError) — Tanaka Akira <akr@...17n.org> 2005/12/28

In article <200512280307.jBS37nnj005909@pbsg500.nifty.com>,

[#28147] Re: ia64-hpux11.23/socket.sl: this executable file can't load extension libraries (LoadError) — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/12/28

山本です。

[#28149] Re: ia64-hpux11.23/socket.sl: this executable file can't load extension libraries (LoadError) — Tanaka Akira <akr@...17n.org> 2005/12/28

In article <20051228210640.13C71A10.ocean@m2.ccsnet.ne.jp>,

[#28151] Re: ia64-hpux11.23/socket.sl: this executable file can't load extension libraries (LoadError) — WATANABE Tetsuya <Tetsuya.WATANABE@...> 2005/12/29

渡辺哲也です。

[#28152] Re: ia64-hpux11.23/socket.sl: this executable file can't load extensionlibraries (LoadError) — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/12/29

山本です。

[#28153] Re: ia64-hpux11.23/socket.sl: this executable file can't load extensionlibraries (LoadError) — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/12/29

山本です。

[#28154] thread based generator.rb — Tanaka Akira <akr@...17n.org> 2005/12/29

In article <20051229114438.44D19F00.ocean@m2.ccsnet.ne.jp>,

[ruby-dev:28193] Re: test_each(TC_SyncEnumerator) fails.

From: "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
Date: 2005-12-30 08:20:39 UTC
List: ruby-dev #28193
山本です。

>deadlock は解決しましたが次のようにテストが失敗します。
>
>% RUBY_ALWAYS_GC= ./ruby -Ilib test/test_generator.rb
>Loaded suite test/test_generator
>Started
>...F
>Finished in 33.273432 seconds.
>
>  1) Failure:
>test_each(TC_SyncEnumerator)
>    [/home/akr/ruby/tmp-ruby/ruby/lib/generator.rb:374:in `test_each'
>     /home/akr/ruby/tmp-ruby/ruby/lib/generator.rb:234:in `each'
>     /home/akr/ruby/tmp-ruby/ruby/lib/generator.rb:218:in `each'
>     /home/akr/ruby/tmp-ruby/ruby/lib/generator.rb:373:in `test_each']:
><["a", 1, 10]> expected but was
><[nil, 1, 10]>.
>
>4 tests, 59 assertions, 1 failures, 0 errors

これも再現しません。Thread.critical の説明に

  注意: I/O や GC、拡張ライブラリがからむとこのフラグは無視されることもあります。
  排他制御を行うにはこのメソッドに頼らず Mutex や Monitor を使うべきです。

とあったので試しに Mutex で実装してみたのですが、これで直ったりしますか?

Index: generator.rb
===================================================================
RCS file: /src/ruby/lib/generator.rb,v
retrieving revision 1.8
diff -u -w -b -p -r1.8 generator.rb
--- generator.rb	30 Dec 2005 06:23:25 -0000	1.8
+++ generator.rb	30 Dec 2005 08:19:30 -0000
@@ -23,6 +23,7 @@
 #
 # See the respective classes for examples of usage.
 
+require "thread"
 
 #
 # Generator converts an internal iterator (i.e. an Enumerable object)
@@ -71,17 +72,24 @@ class Generator
     end
     @index = 0
     @queue = []
+    @mutex = Mutex.new
+    @main_cond = ConditionVariable.new
+    @loop_cond = ConditionVariable.new
+    entered = false
     @loop_thread = Thread.new do
-      Thread.stop
+      @mutex.synchronize do
+        entered = true
+        @loop_cond.wait(@mutex)
       begin
         @block.call(self)
       rescue
-        @main_thread.raise
+          @main_thread.raise $!
       ensure
-        @main_thread.wakeup
+          @main_cond.signal
       end
     end
-    Thread.pass until @loop_thread.stop?
+    end
+    Thread.pass until entered && !@mutex.locked?
     self
   end
 
@@ -90,33 +98,26 @@ class Generator
     if Thread.current != @loop_thread
       raise "should be called in Generator.new{|g| ... }"
     end
-    Thread.critical = true
-    begin
       @queue << value
-      @main_thread.wakeup
-      Thread.stop
-    ensure
-      Thread.critical = false
-    end
+    @main_cond.signal
+    @loop_cond.wait(@mutex)
     self
   end
 
   # Returns true if the generator has reached the end.
   def end?
-    if @queue.empty?
+    @mutex.synchronize do
+      if @queue.empty? && @loop_thread.alive?
       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
+          @loop_cond.signal
+          @main_cond.wait(@mutex)
       ensure
         @main_thread = nil
-        Thread.critical = false
+        end
       end
     end
     @queue.empty?

In This Thread