From 90d9413391ea3f7d05b5cf38e6eef676ec68a529 Mon Sep 17 00:00:00 2001 From: drbrain Date: Sat, 23 Mar 2013 18:35:23 +0000 Subject: Commit miss git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39891 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/rinda/rinda.rb | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) (limited to 'lib/rinda') diff --git a/lib/rinda/rinda.rb b/lib/rinda/rinda.rb index 18e284a544..d9cd3782a0 100644 --- a/lib/rinda/rinda.rb +++ b/lib/rinda/rinda.rb @@ -206,6 +206,50 @@ module Rinda # 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 # 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 ## -- cgit v1.2.3