summaryrefslogtreecommitdiff
path: root/sample/drb/simpletuple.rb
diff options
context:
space:
mode:
Diffstat (limited to 'sample/drb/simpletuple.rb')
-rw-r--r--sample/drb/simpletuple.rb91
1 files changed, 91 insertions, 0 deletions
diff --git a/sample/drb/simpletuple.rb b/sample/drb/simpletuple.rb
new file mode 100644
index 0000000..3ae9208
--- /dev/null
+++ b/sample/drb/simpletuple.rb
@@ -0,0 +1,91 @@
+#!/usr/local/bin/ruby
+# SimpleTupleSpace
+# Copyright (c) 1999-2000 Masatoshi SEKI
+# You can redistribute it and/or modify it under the same terms as Ruby.
+
+require 'thread'
+
+class SimpleTupleSpace
+ def initialize
+ @hash = {}
+ @waiting = {}
+ @hash.taint
+ @waiting.taint
+ self.taint
+ end
+
+ def out(key, obj)
+ Thread.critical = true
+ @hash[key] ||= []
+ @waiting[key] ||= []
+ @hash[key].push obj
+ begin
+ t = @waiting[key].shift
+ @waiting.delete(key) if @waiting[key].length == 0
+ t.wakeup if t
+ rescue ThreadError
+ retry
+ ensure
+ Thread.critical = false
+ end
+ end
+
+ def in(key)
+ Thread.critical = true
+ @hash[key] ||= []
+ @waiting[key] ||= []
+ begin
+ loop do
+ if @hash[key].length == 0
+ @waiting[key].push Thread.current
+ Thread.stop
+ else
+ return @hash[key].shift
+ end
+ end
+ ensure
+ @hash.delete(key) if @hash[key].length == 0
+ Thread.critical = false
+ end
+ end
+end
+
+if __FILE__ == $0
+ ts = SimpleTupleSpace.new
+ clients = []
+ servers = []
+
+ def server(ts)
+ Thread.start {
+ loop do
+ req = ts.in('req')
+ ac = req[0]
+ num = req[1]
+ ts.out(ac, num * num)
+ end
+ }
+ end
+
+ def client(ts, n)
+ Thread.start {
+ ac = Object.new
+ ts.out('req', [ac, n])
+ ans = ts.in(ac)
+ puts "#{n}: #{ans}"
+ }
+ end
+
+ 3.times do
+ servers.push(server(ts))
+ end
+
+ (1..6).each do |n|
+ clients.push(client(ts, n))
+ end
+
+ clients.each do |t|
+ t.join
+ end
+end
+
+