concurrent-ruby 0.6.0 → 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 (110) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +55 -51
  3. data/lib/concurrent/actress/ad_hoc.rb +6 -0
  4. data/lib/concurrent/actress/context.rb +10 -8
  5. data/lib/concurrent/actress/core.rb +44 -20
  6. data/lib/concurrent/actress/core_delegations.rb +5 -0
  7. data/lib/concurrent/actress/envelope.rb +21 -5
  8. data/lib/concurrent/actress/reference.rb +5 -5
  9. data/lib/concurrent/actress.rb +152 -6
  10. data/lib/concurrent/agent.rb +9 -9
  11. data/lib/concurrent/atomic.rb +46 -0
  12. data/lib/concurrent/atomic_reference/concurrent_update_error.rb +7 -0
  13. data/lib/concurrent/atomic_reference/delegated_update.rb +28 -0
  14. data/lib/concurrent/atomic_reference/direct_update.rb +28 -0
  15. data/lib/concurrent/atomic_reference/jruby.rb +8 -0
  16. data/lib/concurrent/atomic_reference/mutex_atomic.rb +47 -0
  17. data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +24 -0
  18. data/lib/concurrent/atomic_reference/rbx.rb +16 -0
  19. data/lib/concurrent/atomic_reference/ruby.rb +16 -0
  20. data/lib/concurrent/atomics.rb +1 -1
  21. data/lib/concurrent/configuration.rb +7 -2
  22. data/lib/concurrent/executor/ruby_thread_pool_executor.rb +0 -1
  23. data/lib/concurrent/executor/{one_by_one.rb → serialized_execution.rb} +21 -8
  24. data/lib/concurrent/executor/timer_set.rb +6 -1
  25. data/lib/concurrent/executors.rb +1 -1
  26. data/lib/concurrent/logging.rb +1 -1
  27. data/lib/concurrent/observable.rb +1 -1
  28. data/lib/concurrent/supervisor.rb +1 -1
  29. data/lib/concurrent/timer_task.rb +0 -36
  30. data/lib/concurrent/version.rb +1 -1
  31. data/lib/concurrent.rb +3 -4
  32. data/lib/concurrent_ruby_ext.so +0 -0
  33. data/lib/extension_helper.rb +9 -0
  34. metadata +19 -152
  35. data/lib/concurrent/actor/actor.rb +0 -270
  36. data/lib/concurrent/actor/postable.rb +0 -102
  37. data/lib/concurrent/actors.rb +0 -2
  38. data/lib/concurrent/actress/doc.md +0 -53
  39. data/lib/concurrent/atomic/atomic.rb +0 -48
  40. data/lib/concurrent/runnable.rb +0 -90
  41. data/lib/concurrent/stoppable.rb +0 -20
  42. data/spec/concurrent/actor/actor_spec.rb +0 -376
  43. data/spec/concurrent/actor/postable_shared.rb +0 -218
  44. data/spec/concurrent/actress_spec.rb +0 -191
  45. data/spec/concurrent/agent_spec.rb +0 -500
  46. data/spec/concurrent/async_spec.rb +0 -352
  47. data/spec/concurrent/atomic/atomic_boolean_spec.rb +0 -172
  48. data/spec/concurrent/atomic/atomic_fixnum_spec.rb +0 -186
  49. data/spec/concurrent/atomic/atomic_spec.rb +0 -133
  50. data/spec/concurrent/atomic/condition_spec.rb +0 -171
  51. data/spec/concurrent/atomic/copy_on_notify_observer_set_spec.rb +0 -10
  52. data/spec/concurrent/atomic/copy_on_write_observer_set_spec.rb +0 -10
  53. data/spec/concurrent/atomic/count_down_latch_spec.rb +0 -151
  54. data/spec/concurrent/atomic/cyclic_barrier_spec.rb +0 -248
  55. data/spec/concurrent/atomic/event_spec.rb +0 -200
  56. data/spec/concurrent/atomic/observer_set_shared.rb +0 -242
  57. data/spec/concurrent/atomic/thread_local_var_spec.rb +0 -113
  58. data/spec/concurrent/channel/buffered_channel_spec.rb +0 -151
  59. data/spec/concurrent/channel/channel_spec.rb +0 -39
  60. data/spec/concurrent/channel/probe_spec.rb +0 -77
  61. data/spec/concurrent/channel/unbuffered_channel_spec.rb +0 -132
  62. data/spec/concurrent/collection/blocking_ring_buffer_spec.rb +0 -149
  63. data/spec/concurrent/collection/priority_queue_spec.rb +0 -317
  64. data/spec/concurrent/collection/ring_buffer_spec.rb +0 -126
  65. data/spec/concurrent/configuration_spec.rb +0 -71
  66. data/spec/concurrent/dataflow_spec.rb +0 -242
  67. data/spec/concurrent/delay_spec.rb +0 -91
  68. data/spec/concurrent/dereferenceable_shared.rb +0 -146
  69. data/spec/concurrent/exchanger_spec.rb +0 -66
  70. data/spec/concurrent/executor/cached_thread_pool_shared.rb +0 -115
  71. data/spec/concurrent/executor/fixed_thread_pool_shared.rb +0 -136
  72. data/spec/concurrent/executor/global_thread_pool_shared.rb +0 -35
  73. data/spec/concurrent/executor/immediate_executor_spec.rb +0 -12
  74. data/spec/concurrent/executor/java_cached_thread_pool_spec.rb +0 -44
  75. data/spec/concurrent/executor/java_fixed_thread_pool_spec.rb +0 -64
  76. data/spec/concurrent/executor/java_single_thread_executor_spec.rb +0 -21
  77. data/spec/concurrent/executor/java_thread_pool_executor_spec.rb +0 -71
  78. data/spec/concurrent/executor/per_thread_executor_spec.rb +0 -57
  79. data/spec/concurrent/executor/ruby_cached_thread_pool_spec.rb +0 -69
  80. data/spec/concurrent/executor/ruby_fixed_thread_pool_spec.rb +0 -39
  81. data/spec/concurrent/executor/ruby_single_thread_executor_spec.rb +0 -18
  82. data/spec/concurrent/executor/ruby_thread_pool_executor_spec.rb +0 -171
  83. data/spec/concurrent/executor/safe_task_executor_spec.rb +0 -103
  84. data/spec/concurrent/executor/thread_pool_class_cast_spec.rb +0 -52
  85. data/spec/concurrent/executor/thread_pool_executor_shared.rb +0 -155
  86. data/spec/concurrent/executor/thread_pool_shared.rb +0 -239
  87. data/spec/concurrent/executor/timer_set_spec.rb +0 -183
  88. data/spec/concurrent/future_spec.rb +0 -329
  89. data/spec/concurrent/ivar_spec.rb +0 -215
  90. data/spec/concurrent/mvar_spec.rb +0 -380
  91. data/spec/concurrent/obligation_shared.rb +0 -102
  92. data/spec/concurrent/obligation_spec.rb +0 -282
  93. data/spec/concurrent/observable_shared.rb +0 -177
  94. data/spec/concurrent/observable_spec.rb +0 -56
  95. data/spec/concurrent/options_parser_spec.rb +0 -71
  96. data/spec/concurrent/promise_spec.rb +0 -367
  97. data/spec/concurrent/runnable_shared.rb +0 -68
  98. data/spec/concurrent/runnable_spec.rb +0 -235
  99. data/spec/concurrent/scheduled_task_spec.rb +0 -342
  100. data/spec/concurrent/stoppable_shared.rb +0 -37
  101. data/spec/concurrent/supervisor_spec.rb +0 -1148
  102. data/spec/concurrent/timer_task_spec.rb +0 -258
  103. data/spec/concurrent/tvar_spec.rb +0 -137
  104. data/spec/concurrent/utility/processor_count_spec.rb +0 -20
  105. data/spec/concurrent/utility/timeout_spec.rb +0 -50
  106. data/spec/concurrent/utility/timer_spec.rb +0 -52
  107. data/spec/spec_helper.rb +0 -31
  108. data/spec/support/example_group_extensions.rb +0 -48
  109. data/spec/support/less_than_or_equal_to_matcher.rb +0 -5
  110. /data/{LICENSE → LICENSE.txt} +0 -0
@@ -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
@@ -1,186 +0,0 @@
1
- require 'spec_helper'
2
-
3
- share_examples_for :atomic_fixnum do
4
-
5
- context 'construction' do
6
-
7
- it 'sets the initial value' do
8
- described_class.new(10).value.should eq 10
9
- end
10
-
11
- it 'defaults the initial value to zero' do
12
- described_class.new.value.should eq 0
13
- end
14
-
15
- it 'raises en exception if the initial value is not a Fixnum' do
16
- lambda {
17
- described_class.new(10.01)
18
- }.should raise_error
19
- end
20
- end
21
-
22
- context '#value' do
23
-
24
- it 'returns the current value' do
25
- counter = described_class.new(10)
26
- counter.value.should eq 10
27
- counter.increment
28
- counter.value.should eq 11
29
- counter.decrement
30
- counter.value.should eq 10
31
- end
32
- end
33
-
34
- context '#value=' do
35
-
36
- it 'sets the #value to the given `Fixnum`' do
37
- atomic = described_class.new(0)
38
- atomic.value = 10
39
- atomic.value.should eq 10
40
- end
41
-
42
- it 'returns the new value' do
43
- atomic = described_class.new(0)
44
- (atomic.value = 10).should eq 10
45
- end
46
-
47
- it 'raises and exception if the value is not a `Fixnum`' do
48
- atomic = described_class.new(0)
49
- expect {
50
- atomic.value = 'foo'
51
- }.to raise_error
52
- end
53
- end
54
-
55
- context '#increment' do
56
-
57
- it 'increases the value by one' do
58
- counter = described_class.new(10)
59
- 3.times{ counter.increment }
60
- counter.value.should eq 13
61
- end
62
-
63
- it 'returns the new value' do
64
- counter = described_class.new(10)
65
- counter.increment.should eq 11
66
- end
67
-
68
- it 'is aliased as #up' do
69
- described_class.new(10).up.should eq 11
70
- end
71
- end
72
-
73
- context '#decrement' do
74
-
75
- it 'decreases the value by one' do
76
- counter = described_class.new(10)
77
- 3.times{ counter.decrement }
78
- counter.value.should eq 7
79
- end
80
-
81
- it 'returns the new value' do
82
- counter = described_class.new(10)
83
- counter.decrement.should eq 9
84
- end
85
-
86
- it 'is aliased as #down' do
87
- described_class.new(10).down.should eq 9
88
- end
89
- end
90
-
91
- context '#compare_and_set' do
92
-
93
- it 'returns false if the value is not found' do
94
- described_class.new(14).compare_and_set(2, 14).should eq false
95
- end
96
-
97
- it 'returns true if the value is found' do
98
- described_class.new(14).compare_and_set(14, 2).should eq true
99
- end
100
-
101
- it 'sets if the value is found' do
102
- f = described_class.new(14)
103
- f.compare_and_set(14, 2)
104
- f.value.should eq 2
105
- end
106
-
107
- it 'does not set if the value is not found' do
108
- f = described_class.new(14)
109
- f.compare_and_set(2, 12)
110
- f.value.should eq 14
111
- end
112
- end
113
- end
114
-
115
- module Concurrent
116
-
117
- describe MutexAtomicFixnum do
118
-
119
- it_should_behave_like :atomic_fixnum
120
-
121
- specify 'construction is synchronized' do
122
- mutex = double('mutex')
123
- Mutex.should_receive(:new).once.with(no_args).and_return(mutex)
124
- described_class.new
125
- end
126
-
127
- specify 'value is synchronized' do
128
- mutex = double('mutex')
129
- Mutex.stub(:new).with(no_args).and_return(mutex)
130
- mutex.should_receive(:lock)
131
- mutex.should_receive(:unlock)
132
- described_class.new.value
133
- end
134
-
135
- specify 'value= is synchronized' do
136
- mutex = double('mutex')
137
- Mutex.stub(:new).with(no_args).and_return(mutex)
138
- mutex.should_receive(:lock)
139
- mutex.should_receive(:unlock)
140
- described_class.new.value = 10
141
- end
142
-
143
- specify 'increment is synchronized' do
144
- mutex = double('mutex')
145
- Mutex.stub(:new).with(no_args).and_return(mutex)
146
- mutex.should_receive(:lock)
147
- mutex.should_receive(:unlock)
148
- described_class.new.increment
149
- end
150
-
151
- specify 'decrement is synchronized' do
152
- mutex = double('mutex')
153
- Mutex.stub(:new).with(no_args).and_return(mutex)
154
- mutex.should_receive(:lock)
155
- mutex.should_receive(:unlock)
156
- described_class.new.decrement
157
- end
158
-
159
- specify 'compare_and_set is synchronized' do
160
- mutex = double('mutex')
161
- Mutex.stub(:new).with(no_args).and_return(mutex)
162
- mutex.should_receive(:lock)
163
- mutex.should_receive(:unlock)
164
- described_class.new(14).compare_and_set(14, 2)
165
- end
166
- end
167
-
168
- if TestHelpers.jruby?
169
-
170
- describe JavaAtomicFixnum do
171
- it_should_behave_like :atomic_fixnum
172
- end
173
- end
174
-
175
- describe AtomicFixnum do
176
- if jruby?
177
- it 'inherits from JavaAtomicFixnum' do
178
- AtomicFixnum.ancestors.should include(JavaAtomicFixnum)
179
- end
180
- else
181
- it 'inherits from MutexAtomicFixnum' do
182
- AtomicFixnum.ancestors.should include(MutexAtomicFixnum)
183
- end
184
- end
185
- end
186
- end