summaryrefslogtreecommitdiff
path: root/lib/rinda
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-03-23 18:35:23 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-03-23 18:35:23 +0000
commit90d9413391ea3f7d05b5cf38e6eef676ec68a529 (patch)
tree9a3392274d6be7af051e55a640dcc88e09c48ed0 /lib/rinda
parentebca3dd3c3fbc903511122078df910362347b5fa (diff)
Commit miss
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39891 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rinda')
-rw-r--r--lib/rinda/rinda.rb50
1 files changed, 47 insertions, 3 deletions
diff --git a/lib/rinda/rinda.rb b/lib/rinda/rinda.rb
index 18e284a..d9cd378 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
##