Stop skipping broken tests
[ruby.git] / sample / drb / old_tuplespace.rb
blob2d5310086e936201c3bf891a274139e278fac838
1 #!/usr/local/bin/ruby
2 # TupleSpace
3 # Copyright (c) 1999-2000 Masatoshi SEKI
4 # You can redistribute it and/or modify it under the same terms as Ruby.
6 class TupleSpace
7   class Template
8     def initialize(list)
9       @list = list
10       @check_idx = []
11       @list.each_with_index do |x, i|
12         @check_idx.push i if x
13       end
14       @size = @list.size
15     end
17     attr :size
18     alias length size
20     def match(tuple)
21       return nil if tuple.size != self.size
22       @check_idx.each do |i|
23         unless @list[i] === tuple[i]
24           return false
25         end
26       end
27       return true
28     end
29   end
31   def initialize
32     @que = {}
33     @waiting = {}
34     @que.taint          # enable tainted communication
35     @waiting.taint
36     self.taint
37   end
39   def wakeup_waiting(tuple)
40     sz = tuple.length
41     return nil unless @waiting[sz]
43     x = nil
44     i = -1
45     found = false
46     @waiting[sz] = @waiting[sz].find_all { |x|
47       if x[0].match(tuple)
48         begin
49           x[1].wakeup
50         rescue ThreadError
51         end
52         false
53       else
54         true
55       end
56     }
57   end
59   def put_waiting(template, thread)
60     sz = template.length
61     @waiting[sz] = [] unless @waiting[sz]
62     @waiting[sz].push([Template.new(template), thread])
63   end
64   private :wakeup_waiting
65   private :put_waiting
67   def get_que(template)
68     sz = template.length
69     return nil unless @que[sz]
71     template = Template.new(template)
73     x = nil
74     i = -1
75     found = false
76     @que[sz].each_with_index do |x, i|
77       if template.match(x)
78         found = true
79         break
80       end
81     end
82     return nil unless found
84     @que[sz].delete_at(i)
86     return x
87   end
89   def put_que(tuple)
90     sz = tuple.length
91     @que[sz] = [] unless @que[sz]
92     @que[sz].push tuple
93   end
94   private :get_que
95   private :put_que
97   def out(*tuples)
98     tuples.each do |tuple|
99       Thread.critical = true
100       put_que(tuple)
101       wakeup_waiting(tuple)
102       Thread.critical = false
103     end
104   end
105   alias put out
106   alias write out
108   def in(template, non_block=false)
109     begin
110       loop do
111         Thread.critical = true
112         tuple = get_que(template)
113         unless tuple
114           if non_block
115             raise ThreadError, "queue empty"
116           end
117           put_waiting(template, Thread.current)
118           Thread.stop
119         else
120           return tuple
121         end
122       end
123     ensure
124       Thread.critical = false
125     end
126   end
127   alias get in
128   alias take in
130   def rd(template, non_block=false)
131     tuple = self.in(template, non_block)
132     out(tuple)
133     tuple
134   end
135   alias read rd
137   def mv(dest, template, non_block=false)
138     tuple = self.in(template, non_block)
139     begin
140       dest.out(tuple)
141     rescue
142       self.out(tuple)
143     end
144   end
145   alias move mv
148 if __FILE__ == $0
149   ts = TupleSpace.new
150   clients = []
151   servers = []
153   def server(ts, id)
154     Thread.start {
155       loop do
156         req = ts.in(['req', nil, nil])
157         ac = req[1]
158         num = req[2]
159         sleep id
160         ts.out([ac, id, num, num * num])
161       end
162     }
163   end
165   def client(ts, n)
166     Thread.start {
167       ac = Object.new
168       tuples = (1..10).collect { |i|
169         ['req', ac, i * 10 + n]
170       }
171       ts.out(*tuples)
172       ts.out(tuples[0])
173       puts "out: #{n}"
174       11.times do |i|
175         ans = ts.in([ac, nil, nil, nil])
176         puts "client(#{n}) server(#{ans[1]}) #{ans[2]} #{ans[3]}"
177       end
178     }
179   end
181   def watcher(ts)
182     Thread.start {
183       loop do
184         begin
185           sleep 1
186           p ts.rd(['req', nil, nil], true)
187         rescue ThreadError
188           puts "'req' not found."
189         end
190       end
191     }
192   end
194   (0..3).each do |n|
195     servers.push(server(ts, n))
196   end
198   (1..6).each do |n|
199     clients.push(client(ts, n))
200   end
202   (1..3).each do
203     watcher(ts)
204   end
206   clients.each do |t|
207     t.join
208   end