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.
- checksums.yaml +4 -4
- data/README.md +55 -51
- data/lib/concurrent/actress/ad_hoc.rb +6 -0
- data/lib/concurrent/actress/context.rb +10 -8
- data/lib/concurrent/actress/core.rb +44 -20
- data/lib/concurrent/actress/core_delegations.rb +5 -0
- data/lib/concurrent/actress/envelope.rb +21 -5
- data/lib/concurrent/actress/reference.rb +5 -5
- data/lib/concurrent/actress.rb +152 -6
- data/lib/concurrent/agent.rb +9 -9
- data/lib/concurrent/atomic.rb +46 -0
- data/lib/concurrent/atomic_reference/concurrent_update_error.rb +7 -0
- data/lib/concurrent/atomic_reference/delegated_update.rb +28 -0
- data/lib/concurrent/atomic_reference/direct_update.rb +28 -0
- data/lib/concurrent/atomic_reference/jruby.rb +8 -0
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +47 -0
- data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +24 -0
- data/lib/concurrent/atomic_reference/rbx.rb +16 -0
- data/lib/concurrent/atomic_reference/ruby.rb +16 -0
- data/lib/concurrent/atomics.rb +1 -1
- data/lib/concurrent/configuration.rb +7 -2
- data/lib/concurrent/executor/ruby_thread_pool_executor.rb +0 -1
- data/lib/concurrent/executor/{one_by_one.rb → serialized_execution.rb} +21 -8
- data/lib/concurrent/executor/timer_set.rb +6 -1
- data/lib/concurrent/executors.rb +1 -1
- data/lib/concurrent/logging.rb +1 -1
- data/lib/concurrent/observable.rb +1 -1
- data/lib/concurrent/supervisor.rb +1 -1
- data/lib/concurrent/timer_task.rb +0 -36
- data/lib/concurrent/version.rb +1 -1
- data/lib/concurrent.rb +3 -4
- data/lib/concurrent_ruby_ext.so +0 -0
- data/lib/extension_helper.rb +9 -0
- metadata +19 -152
- data/lib/concurrent/actor/actor.rb +0 -270
- data/lib/concurrent/actor/postable.rb +0 -102
- data/lib/concurrent/actors.rb +0 -2
- data/lib/concurrent/actress/doc.md +0 -53
- data/lib/concurrent/atomic/atomic.rb +0 -48
- data/lib/concurrent/runnable.rb +0 -90
- data/lib/concurrent/stoppable.rb +0 -20
- data/spec/concurrent/actor/actor_spec.rb +0 -376
- data/spec/concurrent/actor/postable_shared.rb +0 -218
- data/spec/concurrent/actress_spec.rb +0 -191
- data/spec/concurrent/agent_spec.rb +0 -500
- data/spec/concurrent/async_spec.rb +0 -352
- data/spec/concurrent/atomic/atomic_boolean_spec.rb +0 -172
- data/spec/concurrent/atomic/atomic_fixnum_spec.rb +0 -186
- data/spec/concurrent/atomic/atomic_spec.rb +0 -133
- data/spec/concurrent/atomic/condition_spec.rb +0 -171
- data/spec/concurrent/atomic/copy_on_notify_observer_set_spec.rb +0 -10
- data/spec/concurrent/atomic/copy_on_write_observer_set_spec.rb +0 -10
- data/spec/concurrent/atomic/count_down_latch_spec.rb +0 -151
- data/spec/concurrent/atomic/cyclic_barrier_spec.rb +0 -248
- data/spec/concurrent/atomic/event_spec.rb +0 -200
- data/spec/concurrent/atomic/observer_set_shared.rb +0 -242
- data/spec/concurrent/atomic/thread_local_var_spec.rb +0 -113
- data/spec/concurrent/channel/buffered_channel_spec.rb +0 -151
- data/spec/concurrent/channel/channel_spec.rb +0 -39
- data/spec/concurrent/channel/probe_spec.rb +0 -77
- data/spec/concurrent/channel/unbuffered_channel_spec.rb +0 -132
- data/spec/concurrent/collection/blocking_ring_buffer_spec.rb +0 -149
- data/spec/concurrent/collection/priority_queue_spec.rb +0 -317
- data/spec/concurrent/collection/ring_buffer_spec.rb +0 -126
- data/spec/concurrent/configuration_spec.rb +0 -71
- data/spec/concurrent/dataflow_spec.rb +0 -242
- data/spec/concurrent/delay_spec.rb +0 -91
- data/spec/concurrent/dereferenceable_shared.rb +0 -146
- data/spec/concurrent/exchanger_spec.rb +0 -66
- data/spec/concurrent/executor/cached_thread_pool_shared.rb +0 -115
- data/spec/concurrent/executor/fixed_thread_pool_shared.rb +0 -136
- data/spec/concurrent/executor/global_thread_pool_shared.rb +0 -35
- data/spec/concurrent/executor/immediate_executor_spec.rb +0 -12
- data/spec/concurrent/executor/java_cached_thread_pool_spec.rb +0 -44
- data/spec/concurrent/executor/java_fixed_thread_pool_spec.rb +0 -64
- data/spec/concurrent/executor/java_single_thread_executor_spec.rb +0 -21
- data/spec/concurrent/executor/java_thread_pool_executor_spec.rb +0 -71
- data/spec/concurrent/executor/per_thread_executor_spec.rb +0 -57
- data/spec/concurrent/executor/ruby_cached_thread_pool_spec.rb +0 -69
- data/spec/concurrent/executor/ruby_fixed_thread_pool_spec.rb +0 -39
- data/spec/concurrent/executor/ruby_single_thread_executor_spec.rb +0 -18
- data/spec/concurrent/executor/ruby_thread_pool_executor_spec.rb +0 -171
- data/spec/concurrent/executor/safe_task_executor_spec.rb +0 -103
- data/spec/concurrent/executor/thread_pool_class_cast_spec.rb +0 -52
- data/spec/concurrent/executor/thread_pool_executor_shared.rb +0 -155
- data/spec/concurrent/executor/thread_pool_shared.rb +0 -239
- data/spec/concurrent/executor/timer_set_spec.rb +0 -183
- data/spec/concurrent/future_spec.rb +0 -329
- data/spec/concurrent/ivar_spec.rb +0 -215
- data/spec/concurrent/mvar_spec.rb +0 -380
- data/spec/concurrent/obligation_shared.rb +0 -102
- data/spec/concurrent/obligation_spec.rb +0 -282
- data/spec/concurrent/observable_shared.rb +0 -177
- data/spec/concurrent/observable_spec.rb +0 -56
- data/spec/concurrent/options_parser_spec.rb +0 -71
- data/spec/concurrent/promise_spec.rb +0 -367
- data/spec/concurrent/runnable_shared.rb +0 -68
- data/spec/concurrent/runnable_spec.rb +0 -235
- data/spec/concurrent/scheduled_task_spec.rb +0 -342
- data/spec/concurrent/stoppable_shared.rb +0 -37
- data/spec/concurrent/supervisor_spec.rb +0 -1148
- data/spec/concurrent/timer_task_spec.rb +0 -258
- data/spec/concurrent/tvar_spec.rb +0 -137
- data/spec/concurrent/utility/processor_count_spec.rb +0 -20
- data/spec/concurrent/utility/timeout_spec.rb +0 -50
- data/spec/concurrent/utility/timer_spec.rb +0 -52
- data/spec/spec_helper.rb +0 -31
- data/spec/support/example_group_extensions.rb +0 -48
- data/spec/support/less_than_or_equal_to_matcher.rb +0 -5
- /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
|