concurrent-ruby 0.6.1 → 0.7.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/concurrent.rb +3 -4
  4. data/lib/concurrent/atomic.rb +46 -0
  5. data/lib/concurrent/atomic_reference/concurrent_update_error.rb +7 -0
  6. data/lib/concurrent/atomic_reference/delegated_update.rb +28 -0
  7. data/lib/concurrent/atomic_reference/direct_update.rb +28 -0
  8. data/lib/concurrent/atomic_reference/jruby.rb +8 -0
  9. data/lib/concurrent/atomic_reference/mutex_atomic.rb +47 -0
  10. data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +24 -0
  11. data/lib/concurrent/atomic_reference/rbx.rb +16 -0
  12. data/lib/concurrent/atomic_reference/ruby.rb +16 -0
  13. data/lib/concurrent/atomics.rb +1 -1
  14. data/lib/concurrent/configuration.rb +1 -1
  15. data/lib/concurrent/supervisor.rb +1 -1
  16. data/lib/concurrent/timer_task.rb +0 -36
  17. data/lib/concurrent/version.rb +1 -1
  18. data/lib/concurrent_ruby_ext.so +0 -0
  19. data/lib/extension_helper.rb +9 -0
  20. metadata +16 -148
  21. data/lib/concurrent/actor/actor.rb +0 -270
  22. data/lib/concurrent/actor/postable.rb +0 -102
  23. data/lib/concurrent/actors.rb +0 -2
  24. data/lib/concurrent/atomic/atomic.rb +0 -48
  25. data/lib/concurrent/runnable.rb +0 -90
  26. data/lib/concurrent/stoppable.rb +0 -20
  27. data/spec/concurrent/actor/actor_spec.rb +0 -376
  28. data/spec/concurrent/actor/postable_shared.rb +0 -218
  29. data/spec/concurrent/actress_spec.rb +0 -211
  30. data/spec/concurrent/agent_spec.rb +0 -500
  31. data/spec/concurrent/async_spec.rb +0 -352
  32. data/spec/concurrent/atomic/atomic_boolean_spec.rb +0 -172
  33. data/spec/concurrent/atomic/atomic_fixnum_spec.rb +0 -186
  34. data/spec/concurrent/atomic/atomic_spec.rb +0 -133
  35. data/spec/concurrent/atomic/condition_spec.rb +0 -171
  36. data/spec/concurrent/atomic/copy_on_notify_observer_set_spec.rb +0 -10
  37. data/spec/concurrent/atomic/copy_on_write_observer_set_spec.rb +0 -10
  38. data/spec/concurrent/atomic/count_down_latch_spec.rb +0 -151
  39. data/spec/concurrent/atomic/cyclic_barrier_spec.rb +0 -248
  40. data/spec/concurrent/atomic/event_spec.rb +0 -200
  41. data/spec/concurrent/atomic/observer_set_shared.rb +0 -242
  42. data/spec/concurrent/atomic/thread_local_var_spec.rb +0 -113
  43. data/spec/concurrent/channel/buffered_channel_spec.rb +0 -151
  44. data/spec/concurrent/channel/channel_spec.rb +0 -39
  45. data/spec/concurrent/channel/probe_spec.rb +0 -77
  46. data/spec/concurrent/channel/unbuffered_channel_spec.rb +0 -132
  47. data/spec/concurrent/collection/blocking_ring_buffer_spec.rb +0 -149
  48. data/spec/concurrent/collection/priority_queue_spec.rb +0 -317
  49. data/spec/concurrent/collection/ring_buffer_spec.rb +0 -126
  50. data/spec/concurrent/configuration_spec.rb +0 -69
  51. data/spec/concurrent/dataflow_spec.rb +0 -242
  52. data/spec/concurrent/delay_spec.rb +0 -91
  53. data/spec/concurrent/dereferenceable_shared.rb +0 -146
  54. data/spec/concurrent/exchanger_spec.rb +0 -66
  55. data/spec/concurrent/executor/cached_thread_pool_shared.rb +0 -115
  56. data/spec/concurrent/executor/fixed_thread_pool_shared.rb +0 -136
  57. data/spec/concurrent/executor/global_thread_pool_shared.rb +0 -35
  58. data/spec/concurrent/executor/immediate_executor_spec.rb +0 -12
  59. data/spec/concurrent/executor/java_cached_thread_pool_spec.rb +0 -44
  60. data/spec/concurrent/executor/java_fixed_thread_pool_spec.rb +0 -64
  61. data/spec/concurrent/executor/java_single_thread_executor_spec.rb +0 -21
  62. data/spec/concurrent/executor/java_thread_pool_executor_spec.rb +0 -71
  63. data/spec/concurrent/executor/per_thread_executor_spec.rb +0 -57
  64. data/spec/concurrent/executor/ruby_cached_thread_pool_spec.rb +0 -69
  65. data/spec/concurrent/executor/ruby_fixed_thread_pool_spec.rb +0 -39
  66. data/spec/concurrent/executor/ruby_single_thread_executor_spec.rb +0 -18
  67. data/spec/concurrent/executor/ruby_thread_pool_executor_spec.rb +0 -171
  68. data/spec/concurrent/executor/safe_task_executor_spec.rb +0 -103
  69. data/spec/concurrent/executor/thread_pool_class_cast_spec.rb +0 -52
  70. data/spec/concurrent/executor/thread_pool_executor_shared.rb +0 -155
  71. data/spec/concurrent/executor/thread_pool_shared.rb +0 -269
  72. data/spec/concurrent/executor/timer_set_spec.rb +0 -183
  73. data/spec/concurrent/future_spec.rb +0 -329
  74. data/spec/concurrent/ivar_spec.rb +0 -215
  75. data/spec/concurrent/mvar_spec.rb +0 -380
  76. data/spec/concurrent/obligation_shared.rb +0 -102
  77. data/spec/concurrent/obligation_spec.rb +0 -282
  78. data/spec/concurrent/observable_shared.rb +0 -177
  79. data/spec/concurrent/observable_spec.rb +0 -56
  80. data/spec/concurrent/options_parser_spec.rb +0 -71
  81. data/spec/concurrent/promise_spec.rb +0 -367
  82. data/spec/concurrent/runnable_shared.rb +0 -68
  83. data/spec/concurrent/runnable_spec.rb +0 -235
  84. data/spec/concurrent/scheduled_task_spec.rb +0 -340
  85. data/spec/concurrent/stoppable_shared.rb +0 -37
  86. data/spec/concurrent/supervisor_spec.rb +0 -1149
  87. data/spec/concurrent/timer_task_spec.rb +0 -256
  88. data/spec/concurrent/tvar_spec.rb +0 -137
  89. data/spec/concurrent/utility/processor_count_spec.rb +0 -20
  90. data/spec/concurrent/utility/timeout_spec.rb +0 -50
  91. data/spec/concurrent/utility/timer_spec.rb +0 -52
  92. data/spec/spec_helper.rb +0 -41
  93. data/spec/support/example_group_extensions.rb +0 -52
  94. data/spec/support/less_than_or_equal_to_matcher.rb +0 -5
@@ -1,215 +0,0 @@
1
- require 'spec_helper'
2
- require_relative 'dereferenceable_shared'
3
- require_relative 'obligation_shared'
4
- require_relative 'observable_shared'
5
-
6
- module Concurrent
7
-
8
- describe IVar do
9
-
10
- let!(:value) { 10 }
11
-
12
- subject do
13
- i = IVar.new
14
- i.set(14)
15
- i
16
- end
17
-
18
- context 'behavior' do
19
-
20
- # obligation
21
-
22
- let!(:fulfilled_value) { 10 }
23
- let(:rejected_reason) { StandardError.new('Boom!') }
24
-
25
- let(:pending_subject) do
26
- @i = IVar.new
27
- Thread.new do
28
- sleep(3)
29
- @i.set(fulfilled_value)
30
- end
31
- @i
32
- end
33
-
34
- let(:fulfilled_subject) do
35
- i = IVar.new
36
- i.set(fulfilled_value)
37
- i
38
- end
39
-
40
- let(:rejected_subject) do
41
- i = IVar.new
42
- i.fail(rejected_reason)
43
- i
44
- end
45
-
46
- it_should_behave_like :obligation
47
-
48
- # dereferenceable
49
-
50
- def dereferenceable_subject(value, opts = {})
51
- IVar.new(value, opts)
52
- end
53
-
54
- def dereferenceable_observable(opts = {})
55
- IVar.new(IVar::NO_VALUE, opts)
56
- end
57
-
58
- def execute_dereferenceable(subject)
59
- subject.set('value')
60
- end
61
-
62
- it_should_behave_like :dereferenceable
63
-
64
- # observable
65
-
66
- subject{ IVar.new }
67
-
68
- def trigger_observable(observable)
69
- observable.set('value')
70
- end
71
-
72
- it_should_behave_like :observable
73
- end
74
-
75
- context '#initialize' do
76
-
77
- it 'does not have to set an initial value' do
78
- i = IVar.new
79
- i.should be_incomplete
80
- end
81
-
82
- it 'does not set an initial value if you pass NO_VALUE' do
83
- i = IVar.new(IVar::NO_VALUE)
84
- i.should be_incomplete
85
- end
86
-
87
- it 'can set an initial value' do
88
- i = IVar.new(14)
89
- i.should be_completed
90
- end
91
-
92
- end
93
-
94
- context '#set' do
95
-
96
- it 'sets the state to be fulfilled' do
97
- i = IVar.new
98
- i.set(14)
99
- i.should be_fulfilled
100
- end
101
-
102
- it 'sets the value' do
103
- i = IVar.new
104
- i.set(14)
105
- i.value.should eq 14
106
- end
107
-
108
- it 'raises an exception if set more than once' do
109
- i = IVar.new
110
- i.set(14)
111
- expect {i.set(2)}.to raise_error(Concurrent::MultipleAssignmentError)
112
- i.value.should eq 14
113
- end
114
-
115
- it 'returns self' do
116
- i = IVar.new
117
- i.set(42).should eq i
118
- end
119
- end
120
-
121
- context '#fail' do
122
-
123
- it 'sets the state to be rejected' do
124
- i = IVar.new
125
- i.fail
126
- i.should be_rejected
127
- end
128
-
129
- it 'sets the value to be nil' do
130
- i = IVar.new
131
- i.fail
132
- i.value.should be_nil
133
- end
134
-
135
- it 'raises an exception if set more than once' do
136
- i = IVar.new
137
- i.fail
138
- expect {i.fail}.to raise_error(Concurrent::MultipleAssignmentError)
139
- i.value.should be_nil
140
- end
141
-
142
- it 'defaults the reason to a StandardError' do
143
- i = IVar.new
144
- i.fail
145
- i.reason.should be_a StandardError
146
- end
147
-
148
- it 'returns self' do
149
- i = IVar.new
150
- i.fail.should eq i
151
- end
152
- end
153
-
154
- context 'observation' do
155
-
156
- let(:clazz) do
157
- Class.new do
158
- attr_reader :value
159
- attr_reader :reason
160
- attr_reader :count
161
- define_method(:update) do |time, value, reason|
162
- @count = @count.to_i + 1
163
- @value = value
164
- @reason = reason
165
- end
166
- end
167
- end
168
-
169
- let(:observer) { clazz.new }
170
-
171
- it 'notifies all observers on #set' do
172
- i = IVar.new
173
- i.add_observer(observer)
174
-
175
- i.set(42)
176
-
177
- observer.value.should == 42
178
- observer.reason.should be_nil
179
- end
180
-
181
- context 'deadlock avoidance' do
182
-
183
- def reentrant_observer(i)
184
- obs = Object.new
185
- obs.define_singleton_method(:update) do |time, value, reason|
186
- @value = i.value
187
- end
188
- obs.define_singleton_method(:value) { @value }
189
- obs
190
- end
191
-
192
- it 'should notify observers outside mutex lock' do
193
- i = IVar.new
194
- obs = reentrant_observer(i)
195
-
196
- i.add_observer(obs)
197
- i.set(42)
198
-
199
- obs.value.should eq 42
200
- end
201
-
202
- it 'should notify a new observer added after fulfillment outside lock' do
203
- i = IVar.new
204
- i.set(42)
205
- obs = reentrant_observer(i)
206
-
207
- i.add_observer(obs)
208
-
209
- obs.value.should eq 42
210
- end
211
- end
212
-
213
- end
214
- end
215
- end
@@ -1,380 +0,0 @@
1
- require 'spec_helper'
2
- require_relative 'dereferenceable_shared'
3
-
4
- module Concurrent
5
-
6
- describe MVar do
7
-
8
- context 'behavior' do
9
-
10
- # dereferenceable
11
-
12
- def dereferenceable_subject(value, opts = {})
13
- MVar.new(value, opts)
14
- end
15
-
16
- it_should_behave_like :dereferenceable
17
- end
18
-
19
- describe '#initialize' do
20
-
21
- it 'accepts no initial value' do
22
- m = MVar.new
23
- m.should be_empty
24
- end
25
-
26
- it 'accepts an empty initial value' do
27
- m = MVar.new(MVar::EMPTY)
28
- m.should be_empty
29
- end
30
-
31
- it 'accepts an initial value' do
32
- m = MVar.new(14)
33
- m.should_not be_empty
34
- end
35
-
36
- it 'accepts a nil initial value' do
37
- m = MVar.new(nil)
38
- m.should_not be_empty
39
- end
40
-
41
- end
42
-
43
- describe '#take' do
44
-
45
- it 'sets the MVar to empty' do
46
- m = MVar.new(14)
47
- m.take
48
- m.should be_empty
49
- end
50
-
51
- it 'returns the value on a full MVar' do
52
- m = MVar.new(14)
53
- m.take.should eq 14
54
- end
55
-
56
- it 'waits for another thread to #put' do
57
- m = MVar.new
58
-
59
- putter = Thread.new {
60
- sleep(0.1)
61
- m.put 14
62
- }
63
-
64
- m.take.should eq 14
65
- end
66
-
67
- it 'returns TIMEOUT on timeout on an empty MVar' do
68
- m = MVar.new
69
- m.take(0.1).should eq MVar::TIMEOUT
70
- end
71
-
72
- end
73
-
74
- describe '#put' do
75
-
76
- it 'sets the MVar to be empty' do
77
- m = MVar.new(14)
78
- m.take
79
- m.should be_empty
80
- end
81
-
82
- it 'sets a new value on an empty MVar' do
83
- m = MVar.new
84
- m.put 14
85
- m.take.should eq 14
86
- end
87
-
88
- it 'waits for another thread to #take' do
89
- m = MVar.new(14)
90
-
91
- putter = Thread.new {
92
- sleep(0.1)
93
- m.take
94
- }
95
-
96
- m.put(14).should eq 14
97
- end
98
-
99
- it 'returns TIMEOUT on timeout on a full MVar' do
100
- m = MVar.new(14)
101
- m.put(14, 0.1).should eq MVar::TIMEOUT
102
- end
103
-
104
- it 'returns the value' do
105
- m = MVar.new
106
- m.put(14).should eq 14
107
- end
108
-
109
- end
110
-
111
- describe '#empty?' do
112
-
113
- it 'returns true on an empty MVar' do
114
- m = MVar.new
115
- m.should be_empty
116
- end
117
-
118
- it 'returns false on a full MVar' do
119
- m = MVar.new(14)
120
- m.should_not be_empty
121
- end
122
-
123
- end
124
-
125
- describe '#full?' do
126
-
127
- it 'returns false on an empty MVar' do
128
- m = MVar.new
129
- m.should_not be_full
130
- end
131
-
132
- it 'returns true on a full MVar' do
133
- m = MVar.new(14)
134
- m.should be_full
135
- end
136
-
137
- end
138
-
139
- describe '#modify' do
140
-
141
- it 'raises an exception when no block given' do
142
- m = MVar.new(14)
143
- expect { m.modify }.to raise_error(ArgumentError)
144
- end
145
-
146
- it 'modifies a full MVar' do
147
- m = MVar.new(14)
148
- m.modify{ |v| v + 2 }
149
- m.take.should eq 16
150
- end
151
-
152
- it 'returns the unmodified value' do
153
- m = MVar.new(14)
154
- m.modify{ |v| v + 2 }.should eq 14
155
- end
156
-
157
- it 'waits for another thread to #put' do
158
- m = MVar.new
159
-
160
- putter = Thread.new {
161
- sleep(0.1)
162
- m.put 14
163
- }
164
-
165
- m.modify{ |v| v + 2 }.should eq 14
166
- end
167
-
168
- it 'is atomic' do
169
- m = MVar.new(0)
170
-
171
- # #modify conceptually does #take and #put - but it should be atomic.
172
- # Check that another #put can't sneak it during the #modify.
173
-
174
- modifier = Thread.new {
175
- m.modify do |v|
176
- sleep(0.5)
177
- 1
178
- end
179
- }
180
-
181
- sleep(0.1)
182
- m.put(2, 0.5).should eq MVar::TIMEOUT
183
- m.take.should eq 1
184
- end
185
-
186
- it 'returns TIMEOUT on timeout on an empty MVar' do
187
- m = MVar.new
188
- m.modify(0.1){ |v| v + 2 }.should eq MVar::TIMEOUT
189
- end
190
-
191
- end
192
-
193
- describe '#try_put!' do
194
-
195
- it 'returns true an empty MVar' do
196
- m = MVar.new
197
- m.try_put!(14).should eq true
198
- end
199
-
200
- it 'returns false on a full MVar' do
201
- m = MVar.new(14)
202
- m.try_put!(14).should eq false
203
- end
204
-
205
- it 'sets an empty MVar to be full' do
206
- m = MVar.new
207
- m.try_put! 14
208
- m.should be_full
209
- end
210
-
211
- end
212
-
213
- describe '#try_take!' do
214
-
215
- it 'returns EMPTY an empty MVar' do
216
- m = MVar.new
217
- m.try_take!.should eq MVar::EMPTY
218
- end
219
-
220
- it 'returns the value on a full MVar' do
221
- m = MVar.new(14)
222
- m.try_take!.should eq 14
223
- end
224
-
225
- it 'sets a full MVar to be empty' do
226
- m = MVar.new(14)
227
- m.try_take!
228
- m.should be_empty
229
- end
230
-
231
- end
232
-
233
- describe '#set!' do
234
-
235
- it 'sets an empty MVar to be full' do
236
- m = MVar.new
237
- m.set! 14
238
- m.should be_full
239
- end
240
-
241
- it 'sets a full MVar to be full' do
242
- m = MVar.new(2)
243
- m.set! 14
244
- m.should be_full
245
- m.take.should eq 14
246
- end
247
-
248
- it 'returns EMPTY on an empty MVar' do
249
- m = MVar.new
250
- m.set!(2).should eq MVar::EMPTY
251
- end
252
-
253
- it 'returns the original value on a full MVar' do
254
- m = MVar.new(14)
255
- m.set!(2).should eq 14
256
- end
257
-
258
- end
259
-
260
- describe '#modify!' do
261
-
262
- it 'raises an exception when no block given' do
263
- m = MVar.new(14)
264
- expect { m.modify! }.to raise_error(ArgumentError)
265
- end
266
-
267
- it 'modifies a full MVar' do
268
- m = MVar.new(14)
269
- m.modify!{ |v| v + 2 }
270
- m.take.should eq 16
271
- end
272
-
273
- it 'modifies an empty MVar' do
274
- m = MVar.new
275
- m.modify!{ |v| 14 }
276
- m.take.should eq 14
277
- end
278
-
279
- it 'can be used to set a full MVar to empty' do
280
- m = MVar.new(14)
281
- m.modify!{ |v| MVar::EMPTY }
282
- m.should be_empty
283
- end
284
-
285
- it 'can be used to set an empty MVar to empty' do
286
- m = MVar.new
287
- m.modify!{ |v| MVar::EMPTY }
288
- m.should be_empty
289
- end
290
-
291
- it 'returns the unmodified value' do
292
- m = MVar.new(14)
293
- m.modify!{ |v| v + 2 }.should eq 14
294
- end
295
-
296
- end
297
-
298
- context 'spurious wake ups' do
299
-
300
- let(:m) { MVar.new }
301
-
302
- before(:each) do
303
- def m.simulate_spurious_wake_up
304
- @mutex.synchronize do
305
- @full_condition.broadcast
306
- @empty_condition.broadcast
307
- end
308
- end
309
- end
310
-
311
- describe '#take' do
312
- it 'waits for another thread to #put' do
313
- Thread.new { sleep(0.5); m.put 14 }
314
- Thread.new { sleep(0.1); m.simulate_spurious_wake_up }
315
-
316
- m.take.should eq 14
317
- end
318
-
319
- it 'returns TIMEOUT on timeout on an empty MVar' do
320
- result = nil
321
- Thread.new { result = m.take(0.3) }
322
- sleep(0.1)
323
- Thread.new { m.simulate_spurious_wake_up }
324
- sleep(0.1)
325
- result.should be_nil
326
- sleep(0.2)
327
- result.should eq MVar::TIMEOUT
328
- end
329
- end
330
-
331
- describe '#modify' do
332
-
333
- it 'waits for another thread to #put' do
334
- Thread.new { sleep(0.5); m.put 14 }
335
- Thread.new { sleep(0.1); m.simulate_spurious_wake_up }
336
-
337
- m.modify{ |v| v + 2 }.should eq 14
338
- end
339
-
340
- it 'returns TIMEOUT on timeout on an empty MVar' do
341
- result = nil
342
- Thread.new { result = m.modify(0.3){ |v| v + 2 } }
343
- sleep(0.1)
344
- Thread.new { m.simulate_spurious_wake_up }
345
- sleep(0.1)
346
- result.should be_nil
347
- sleep(0.2)
348
- result.should eq MVar::TIMEOUT
349
- end
350
- end
351
-
352
- describe '#put' do
353
-
354
- before(:each) { m.put(42) }
355
-
356
- it 'waits for another thread to #take' do
357
- Thread.new { sleep(0.5); m.take }
358
- Thread.new { sleep(0.1); m.simulate_spurious_wake_up }
359
-
360
- m.put(14).should eq 14
361
- end
362
-
363
- it 'returns TIMEOUT on timeout on a full MVar' do
364
- result = nil
365
- Thread.new { result = m.put(14, 0.3) }
366
- sleep(0.1)
367
- Thread.new { m.simulate_spurious_wake_up }
368
- sleep(0.1)
369
- result.should be_nil
370
- sleep(0.2)
371
- result.should eq MVar::TIMEOUT
372
- end
373
- end
374
-
375
-
376
- end
377
-
378
- end
379
-
380
- end