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,352 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Concurrent
4
-
5
- describe Async do
6
-
7
- let(:executor) { PerThreadExecutor.new }
8
-
9
- let(:async_class) do
10
- Class.new do
11
- include Concurrent::Async
12
- attr_accessor :accessor
13
- def initialize
14
- init_mutex
15
- end
16
- def echo(msg)
17
- msg
18
- end
19
- def gather(first, second = nil)
20
- return first, second
21
- end
22
- def boom(ex = StandardError.new)
23
- raise ex
24
- end
25
- def wait(seconds)
26
- sleep(seconds)
27
- end
28
- def with_block
29
- yield
30
- end
31
- end
32
- end
33
-
34
- subject do
35
- obj = async_class.new
36
- obj.executor = executor
37
- obj
38
- end
39
-
40
- context '#validate_argc' do
41
-
42
- subject do
43
- Class.new {
44
- def zero() nil; end
45
- def three(a, b, c, &block) nil; end
46
- def two_plus_two(a, b, c=nil, d=nil, &block) nil; end
47
- def many(*args, &block) nil; end
48
- }.new
49
- end
50
-
51
- it 'raises an exception when the method is not defined' do
52
- expect {
53
- Async::validate_argc(subject, :bogus)
54
- }.to raise_error(StandardError)
55
- end
56
-
57
- it 'raises an exception for too many args on a zero arity method' do
58
- expect {
59
- Async::validate_argc(subject, :zero, 1, 2, 3)
60
- }.to raise_error(ArgumentError)
61
- end
62
-
63
- it 'does not raise an exception for correct zero arity' do
64
- expect {
65
- Async::validate_argc(subject, :zero)
66
- }.not_to raise_error
67
- end
68
-
69
- it 'raises an exception for too many args on a method with positive arity' do
70
- expect {
71
- Async::validate_argc(subject, :three, 1, 2, 3, 4)
72
- }.to raise_error(ArgumentError)
73
- end
74
-
75
- it 'raises an exception for too few args on a method with positive arity' do
76
- expect {
77
- Async::validate_argc(subject, :three, 1, 2)
78
- }.to raise_error(ArgumentError)
79
- end
80
-
81
- it 'does not raise an exception for correct positive arity' do
82
- expect {
83
- Async::validate_argc(subject, :three, 1, 2, 3)
84
- }.not_to raise_error
85
- end
86
-
87
- it 'raises an exception for too few args on a method with negative arity' do
88
- expect {
89
- Async::validate_argc(subject, :two_plus_two, 1)
90
- }.to raise_error(ArgumentError)
91
- end
92
-
93
- it 'does not raise an exception for correct negative arity' do
94
- expect {
95
- Async::validate_argc(subject, :two_plus_two, 1, 2)
96
- Async::validate_argc(subject, :two_plus_two, 1, 2, 3, 4)
97
- Async::validate_argc(subject, :two_plus_two, 1, 2, 3, 4, 5, 6)
98
-
99
- Async::validate_argc(subject, :many)
100
- Async::validate_argc(subject, :many, 1, 2)
101
- Async::validate_argc(subject, :many, 1, 2, 3, 4)
102
- }.not_to raise_error
103
- end
104
- end
105
-
106
- context 'executor' do
107
-
108
- it 'returns the default executor when #executor= has never been called' do
109
- Concurrent.configuration.should_receive(:global_operation_pool).
110
- and_return(ImmediateExecutor.new)
111
- subject = async_class.new
112
- subject.async.echo(:foo)
113
- end
114
-
115
- it 'returns the memo after #executor= has been called' do
116
- executor = ImmediateExecutor.new
117
- executor.should_receive(:post)
118
- subject = async_class.new
119
- subject.executor = executor
120
- subject.async.echo(:foo)
121
- end
122
-
123
- it 'raises an exception if #executor= is called after initialization complete' do
124
- executor = ImmediateExecutor.new
125
- subject = async_class.new
126
- subject.async.echo(:foo)
127
- expect {
128
- subject.executor = executor
129
- }.to raise_error(ArgumentError)
130
- end
131
- end
132
-
133
- context '#async' do
134
-
135
- it 'raises an error when calling a method that does not exist' do
136
- expect {
137
- subject.async.bogus
138
- }.to raise_error(StandardError)
139
- end
140
-
141
- it 'raises an error when passing too few arguments' do
142
- expect {
143
- subject.async.gather
144
- }.to raise_error(ArgumentError)
145
- end
146
-
147
- it 'raises an error when pasing too many arguments (arity >= 0)' do
148
- expect {
149
- subject.async.echo(1, 2, 3, 4, 5)
150
- }.to raise_error(StandardError)
151
- end
152
-
153
- it 'returns a :pending Future' do
154
- val = subject.async.wait(5)
155
- val.should be_a Concurrent::Future
156
- val.should be_pending
157
- end
158
-
159
- it 'runs the Future on the memoized executor' do
160
- executor = ImmediateExecutor.new
161
- executor.should_receive(:post).with(any_args)
162
- subject = async_class.new
163
- subject.executor = executor
164
- subject.async.echo(:foo)
165
- end
166
-
167
- it 'sets the value on success' do
168
- val = subject.async.echo(:foo)
169
- val.value.should eq :foo
170
- val.should be_fulfilled
171
- end
172
-
173
- it 'sets the reason on failure' do
174
- ex = ArgumentError.new
175
- val = subject.async.boom(ex)
176
- sleep(0.1)
177
- val.reason.should eq ex
178
- val.should be_rejected
179
- end
180
-
181
- it 'sets the reason when giving too many optional arguments' do
182
- val = subject.async.gather(1, 2, 3, 4, 5)
183
- sleep(0.1)
184
- val.reason.should be_a StandardError
185
- val.should be_rejected
186
- end
187
-
188
- it 'supports attribute accessors' do
189
- subject.async.accessor = :foo
190
- sleep(0.1)
191
- val = subject.async.accessor
192
- sleep(0.1)
193
- val.value.should eq :foo
194
- subject.accessor.should eq :foo
195
- end
196
-
197
- it 'supports methods with blocks' do
198
- val = subject.async.with_block{ :foo }
199
- sleep(0.1)
200
- val.value.should eq :foo
201
- end
202
-
203
- it 'is aliased as #future' do
204
- val = subject.future.wait(5)
205
- val.should be_a Concurrent::Future
206
- end
207
-
208
- context '#method_missing' do
209
-
210
- it 'defines the method after the first call' do
211
- expect { subject.async.method(:echo) }.to raise_error(NameError)
212
- subject.async.echo(:foo)
213
- sleep(0.1)
214
- expect { subject.async.method(:echo) }.not_to raise_error
215
- end
216
-
217
- it 'does not define the method on name/arity exception' do
218
- expect { subject.async.method(:bogus) }.to raise_error(NameError)
219
- expect { subject.async.bogus }.to raise_error(NameError)
220
- expect { subject.async.method(:bogus) }.to raise_error(NameError)
221
- end
222
- end
223
- end
224
-
225
- context '#await' do
226
-
227
- it 'raises an error when calling a method that does not exist' do
228
- expect {
229
- subject.await.bogus
230
- }.to raise_error(StandardError)
231
- end
232
-
233
- it 'raises an error when passing too few arguments' do
234
- expect {
235
- subject.await.gather
236
- }.to raise_error(ArgumentError)
237
- end
238
-
239
- it 'raises an error when pasing too many arguments (arity >= 0)' do
240
- expect {
241
- subject.await.echo(1, 2, 3, 4, 5)
242
- }.to raise_error(StandardError)
243
- end
244
-
245
- it 'returns a :fulfilled IVar' do
246
- val = subject.await.echo(5)
247
- val.should be_a Concurrent::IVar
248
- val.should be_fulfilled
249
- end
250
-
251
- it 'sets the value on success' do
252
- val = subject.await.echo(:foo)
253
- val.value.should eq :foo
254
- val.should be_fulfilled
255
- end
256
-
257
- it 'sets the reason on failure' do
258
- ex = ArgumentError.new
259
- val = subject.await.boom(ex)
260
- val.reason.should eq ex
261
- val.should be_rejected
262
- end
263
-
264
- it 'sets the reason when giving too many optional arguments' do
265
- val = subject.await.gather(1, 2, 3, 4, 5)
266
- val.reason.should be_a StandardError
267
- val.should be_rejected
268
- end
269
-
270
- it 'supports attribute accessors' do
271
- subject.await.accessor = :foo
272
- val = subject.await.accessor
273
- val.value.should eq :foo
274
- subject.accessor.should eq :foo
275
- end
276
-
277
- it 'supports methods with blocks' do
278
- val = subject.await.with_block{ :foo }
279
- val.value.should eq :foo
280
- end
281
-
282
- it 'is aliased as #delay' do
283
- val = subject.delay.echo(5)
284
- val.should be_a Concurrent::IVar
285
- end
286
-
287
- context '#method_missing' do
288
-
289
- it 'defines the method after the first call' do
290
- expect { subject.await.method(:echo) }.to raise_error(NameError)
291
- subject.await.echo(:foo)
292
- expect { subject.await.method(:echo) }.not_to raise_error
293
- end
294
-
295
- it 'does not define the method on name/arity exception' do
296
- expect { subject.await.method(:bogus) }.to raise_error(NameError)
297
- expect { subject.await.bogus }.to raise_error(NameError)
298
- expect { subject.await.method(:bogus) }.to raise_error(NameError)
299
- end
300
- end
301
- end
302
-
303
- context 'locking' do
304
-
305
- it 'uses the same mutex for both #async and #await' do
306
- object = Class.new {
307
- include Concurrent::Async
308
- attr_reader :bucket
309
- def initialize() init_mutex; end
310
- def gather(seconds, first, *rest)
311
- sleep(seconds)
312
- (@bucket ||= []).concat([first])
313
- @bucket.concat(rest)
314
- end
315
- }.new
316
-
317
- object.async.gather(0.5, :a, :b)
318
- sleep(0.1)
319
- object.await.gather(0, :c, :d)
320
- object.bucket.should eq [:a, :b, :c, :d]
321
- end
322
-
323
- context 'raises an InitializationError' do
324
-
325
- let(:async_class) do
326
- Class.new do
327
- include Concurrent::Async
328
- def echo(msg) msg; end
329
- end
330
- end
331
-
332
- it 'when #async is called before #init_mutex' do
333
- expect {
334
- async_class.new.async.echo(:foo)
335
- }.to raise_error(Concurrent::InitializationError)
336
- end
337
-
338
- it 'when #await is called before #init_mutex' do
339
- expect {
340
- async_class.new.async.echo(:foo)
341
- }.to raise_error(Concurrent::InitializationError)
342
- end
343
-
344
- it 'when #executor= is called before #init_mutex' do
345
- expect {
346
- async_class.new.executor = Concurrent::ImmediateExecutor.new
347
- }.to raise_error(Concurrent::InitializationError)
348
- end
349
- end
350
- end
351
- end
352
- end
@@ -1,172 +0,0 @@
1
- require 'spec_helper'
2
-
3
- share_examples_for :atomic_boolean do
4
-
5
- describe 'construction' do
6
-
7
- it 'sets the initial value' do
8
- described_class.new(true).value.should be_true
9
- end
10
-
11
- it 'defaults the initial value to false' do
12
- described_class.new.value.should be_false
13
- end
14
-
15
- it 'evaluates the truthiness of a true value' do
16
- described_class.new(10).value.should be_true
17
- end
18
-
19
- it 'evaluates the truthiness of a false value' do
20
- described_class.new(nil).value.should be_false
21
- end
22
- end
23
-
24
- describe '#value' do
25
-
26
- it 'returns the current value' do
27
- counter = described_class.new(true)
28
- counter.value.should be_true
29
- counter.make_false
30
- counter.value.should be_false
31
- counter.make_true
32
- counter.value.should be_true
33
- end
34
- end
35
-
36
- describe '#value=' do
37
-
38
- it 'sets the #value to the given `Boolean`' do
39
- atomic = described_class.new(true)
40
- atomic.value = false
41
- atomic.value.should be_false
42
- end
43
-
44
- it 'returns the new value' do
45
- atomic = described_class.new(false)
46
- (atomic.value = true).should be_true
47
- end
48
-
49
- it 'evaluates the truthiness of a true value' do
50
- atomic = described_class.new(false)
51
- atomic.value = 10
52
- atomic.value.should be_true
53
- end
54
-
55
- it 'evaluates the truthiness of a false value' do
56
- atomic = described_class.new(true)
57
- atomic.value = nil
58
- atomic.value.should be_false
59
- end
60
- end
61
-
62
- describe '#true?' do
63
-
64
- specify { described_class.new(true).true?.should be_true }
65
-
66
- specify { described_class.new(false).true?.should be_false }
67
- end
68
-
69
- describe '#false?' do
70
-
71
- specify { described_class.new(true).false?.should be_false }
72
-
73
- specify { described_class.new(false).false?.should be_true }
74
- end
75
-
76
- describe '#make_true' do
77
-
78
- it 'makes a false value true and returns true' do
79
- subject = described_class.new(false)
80
- subject.make_true.should be_true
81
- subject.value.should be_true
82
- end
83
-
84
- it 'keeps a true value true and returns false' do
85
- subject = described_class.new(true)
86
- subject.make_true.should be_false
87
- subject.value.should be_true
88
- end
89
- end
90
-
91
- describe '#make_false' do
92
-
93
- it 'makes a true value false and returns true' do
94
- subject = described_class.new(true)
95
- subject.make_false.should be_true
96
- subject.value.should be_false
97
- end
98
-
99
- it 'keeps a false value false and returns false' do
100
- subject = described_class.new(false)
101
- subject.make_false.should be_false
102
- subject.value.should be_false
103
- end
104
- end
105
- end
106
-
107
- module Concurrent
108
-
109
- describe MutexAtomicBoolean do
110
-
111
- it_should_behave_like :atomic_boolean
112
-
113
- specify 'construction is synchronized' do
114
- mutex = double('mutex')
115
- Mutex.should_receive(:new).once.with(no_args).and_return(mutex)
116
- described_class.new
117
- end
118
-
119
- context 'instance methods' do
120
-
121
- before(:each) do
122
- mutex = double('mutex')
123
- Mutex.stub(:new).with(no_args).and_return(mutex)
124
- mutex.should_receive(:lock)
125
- mutex.should_receive(:unlock)
126
- end
127
-
128
- specify 'value is synchronized' do
129
- described_class.new.value
130
- end
131
-
132
- specify 'value= is synchronized' do
133
- described_class.new.value = 10
134
- end
135
-
136
- specify 'true? is synchronized' do
137
- described_class.new.true?
138
- end
139
-
140
- specify 'false? is synchronized' do
141
- described_class.new.false?
142
- end
143
-
144
- specify 'make_true is synchronized' do
145
- described_class.new.make_true
146
- end
147
-
148
- specify 'make_false is synchronized' do
149
- described_class.new.make_false
150
- end
151
- end
152
- end
153
-
154
- if TestHelpers.jruby?
155
-
156
- describe JavaAtomicBoolean do
157
- it_should_behave_like :atomic_boolean
158
- end
159
- end
160
-
161
- describe AtomicBoolean do
162
- if jruby?
163
- it 'inherits from JavaAtomicBoolean' do
164
- AtomicBoolean.ancestors.should include(JavaAtomicBoolean)
165
- end
166
- else
167
- it 'inherits from MutexAtomicBoolean' do
168
- AtomicBoolean.ancestors.should include(MutexAtomicBoolean)
169
- end
170
- end
171
- end
172
- end