concurrent-ruby 0.6.1 → 0.7.0.rc0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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