[前][次][番号順一覧][スレッド一覧]

ruby-changes:27839

From: drbrain <ko1@a...>
Date: Sun, 24 Mar 2013 03:35:32 +0900 (JST)
Subject: [ruby-changes:27839] drbrain:r39891 (trunk): Commit miss

drbrain	2013-03-24 03:35:23 +0900 (Sun, 24 Mar 2013)

  New Revision: 39891

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=39891

  Log:
    Commit miss

  Modified files:
    trunk/lib/rinda/rinda.rb
    trunk/test/rinda/test_rinda.rb

Index: lib/rinda/rinda.rb
===================================================================
--- lib/rinda/rinda.rb	(revision 39890)
+++ lib/rinda/rinda.rb	(revision 39891)
@@ -206,6 +206,50 @@ module Rinda https://github.com/ruby/ruby/blob/trunk/lib/rinda/rinda.rb#L206
   # TupleSpaceProxy allows a remote Tuplespace to appear as local.
 
   class TupleSpaceProxy
+    ##
+    # A Port ensures that a moved tuple arrives properly at its destination
+    # and does not get lost.
+    #
+    # See https://bugs.ruby-lang.org/issues/8125
+
+    class Port # :nodoc:
+      attr_reader :value
+
+      def self.deliver
+        port = new
+
+        begin
+          yield(port)
+        ensure
+          port.close
+        end
+
+        port.value
+      end
+
+      def initialize
+        @open = true
+        @value = nil
+      end
+
+      ##
+      # Don't let the DRb thread push to it when remote sends tuple
+
+      def close
+        @open = false
+      end
+
+      ##
+      # Stores +value+ and ensure it does not get marshaled multiple times.
+
+      def push value
+        raise 'port closed' unless @open
+
+        @value = value
+
+        nil # avoid Marshal
+      end
+    end
 
     ##
     # Creates a new TupleSpaceProxy to wrap +ts+.
@@ -225,9 +269,9 @@ module Rinda https://github.com/ruby/ruby/blob/trunk/lib/rinda/rinda.rb#L269
     # Takes +tuple+ from the proxied TupleSpace.  See TupleSpace#take.
 
     def take(tuple, sec=nil, &block)
-      port = []
-      @ts.move(DRbObject.new(port), tuple, sec, &block)
-      port[0]
+      Port.deliver do |port|
+        @ts.move(DRbObject.new(port), tuple, sec, &block)
+      end
     end
 
     ##
Index: test/rinda/test_rinda.rb
===================================================================
--- test/rinda/test_rinda.rb	(revision 39890)
+++ test/rinda/test_rinda.rb	(revision 39891)
@@ -477,6 +477,46 @@ class TupleSpaceProxyTest < Test::Unit:: https://github.com/ruby/ruby/blob/trunk/test/rinda/test_rinda.rb#L477
                  @ts.take({'head' => 1, 'tail' => 2}, 0))
   end
 
+  def test_take_bug_8215
+    DRb.stop_service
+    service = DRb.start_service(nil, @ts_base)
+
+    uri = service.uri
+
+    take = fork do
+      DRb.stop_service
+      DRb.start_service
+      ro = DRbObject.new_with_uri(uri)
+      ts = Rinda::TupleSpaceProxy.new(ro)
+      th = Thread.new do
+        ts.take([:test_take, nil])
+      end
+      Kernel.sleep(0.1)
+      th.raise(Interrupt) # causes loss of the taken tuple
+      ts.write([:barrier, :continue])
+      Kernel.sleep
+    end
+
+    @ts_base.take([:barrier, :continue])
+
+    write = fork do
+      DRb.stop_service
+      DRb.start_service
+      ro = DRbObject.new_with_uri(uri)
+      ts = Rinda::TupleSpaceProxy.new(ro)
+      ts.write([:test_take, 42])
+    end
+
+    status = Process.wait(write)
+
+    assert_equal([[:test_take, 42]], @ts_base.read_all([:test_take, nil]),
+                 '[bug:8215] tuple lost')
+  ensure
+    Process.kill("TERM", write) if write && status.nil?
+    Process.kill("TERM", take)  if take
+    service.stop_service
+  end
+
   @server = DRb.primary_server || DRb.start_service
 end
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]