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,133 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
share_examples_for :atomic do
|
|
4
|
-
|
|
5
|
-
context 'construction' do
|
|
6
|
-
|
|
7
|
-
it 'sets the initial value' do
|
|
8
|
-
described_class.new(:foo).value.should eq :foo
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
it 'defaults the initial value to nil' do
|
|
12
|
-
described_class.new.value.should eq nil
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
context '#value' do
|
|
17
|
-
|
|
18
|
-
it 'returns the current value' do
|
|
19
|
-
counter = described_class.new(:foo)
|
|
20
|
-
counter.value.should eq :foo
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
context '#value=' do
|
|
25
|
-
|
|
26
|
-
it 'sets the #value to the given object' do
|
|
27
|
-
atomic = described_class.new(:foo)
|
|
28
|
-
atomic.value = :bar
|
|
29
|
-
atomic.value.should eq :bar
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it 'returns the new value' do
|
|
33
|
-
atomic = described_class.new(:foo)
|
|
34
|
-
(atomic.value = :bar).should eq :bar
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
context '#modify' do
|
|
39
|
-
|
|
40
|
-
it 'yields the current value' do
|
|
41
|
-
atomic = described_class.new(:foo)
|
|
42
|
-
current = []
|
|
43
|
-
atomic.modify { |value| current << value }
|
|
44
|
-
current.should eq [:foo]
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
it 'stores the value returned from the yield' do
|
|
48
|
-
atomic = described_class.new(:foo)
|
|
49
|
-
atomic.modify { |value| :bar }
|
|
50
|
-
atomic.value.should eq :bar
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
it 'returns the new value' do
|
|
54
|
-
atomic = described_class.new(:foo)
|
|
55
|
-
atomic.modify{ |value| :bar }.should eq :bar
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
context '#compare_and_set' do
|
|
60
|
-
|
|
61
|
-
it 'returns false if the value is not found' do
|
|
62
|
-
described_class.new(:foo).compare_and_set(:bar, :foo).should eq false
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
it 'returns true if the value is found' do
|
|
66
|
-
described_class.new(:foo).compare_and_set(:foo, :bar).should eq true
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
it 'sets if the value is found' do
|
|
70
|
-
f = described_class.new(:foo)
|
|
71
|
-
f.compare_and_set(:foo, :bar)
|
|
72
|
-
f.value.should eq :bar
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it 'does not set if the value is not found' do
|
|
76
|
-
f = described_class.new(:foo)
|
|
77
|
-
f.compare_and_set(:bar, :baz)
|
|
78
|
-
f.value.should eq :foo
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
module Concurrent
|
|
84
|
-
|
|
85
|
-
describe MutexAtomic do
|
|
86
|
-
|
|
87
|
-
it_should_behave_like :atomic
|
|
88
|
-
|
|
89
|
-
specify 'construction is synchronized' do
|
|
90
|
-
mutex = double('mutex')
|
|
91
|
-
Mutex.should_receive(:new).once.with(no_args).and_return(mutex)
|
|
92
|
-
described_class.new
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
specify 'value is synchronized' do
|
|
96
|
-
mutex = double('mutex')
|
|
97
|
-
Mutex.stub(:new).with(no_args).and_return(mutex)
|
|
98
|
-
mutex.should_receive(:lock)
|
|
99
|
-
mutex.should_receive(:unlock)
|
|
100
|
-
described_class.new.value
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
specify 'value= is synchronized' do
|
|
104
|
-
mutex = double('mutex')
|
|
105
|
-
Mutex.stub(:new).with(no_args).and_return(mutex)
|
|
106
|
-
mutex.should_receive(:lock)
|
|
107
|
-
mutex.should_receive(:unlock)
|
|
108
|
-
described_class.new.value = 10
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
specify 'modify is synchronized' do
|
|
112
|
-
mutex = double('mutex')
|
|
113
|
-
Mutex.stub(:new).with(no_args).and_return(mutex)
|
|
114
|
-
mutex.should_receive(:lock)
|
|
115
|
-
mutex.should_receive(:unlock)
|
|
116
|
-
described_class.new(:foo).modify { |value| value }
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
specify 'compare_and_set is synchronized' do
|
|
120
|
-
mutex = double('mutex')
|
|
121
|
-
Mutex.stub(:new).with(no_args).and_return(mutex)
|
|
122
|
-
mutex.should_receive(:lock)
|
|
123
|
-
mutex.should_receive(:unlock)
|
|
124
|
-
described_class.new(14).compare_and_set(14, 2)
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
describe Atomic do
|
|
129
|
-
it 'inherits from MutexAtomic' do
|
|
130
|
-
Atomic.ancestors.should include(MutexAtomic)
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
end
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
module Concurrent
|
|
4
|
-
|
|
5
|
-
describe Condition do
|
|
6
|
-
|
|
7
|
-
let(:mutex) { Mutex.new }
|
|
8
|
-
subject{ Condition.new }
|
|
9
|
-
|
|
10
|
-
before(:each) do
|
|
11
|
-
# rspec is not thread safe, without mutex initialization
|
|
12
|
-
# we can experience race conditions
|
|
13
|
-
mutex
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
context 'with no waiting threads' do
|
|
17
|
-
describe '#signal' do
|
|
18
|
-
it 'should return immediately' do
|
|
19
|
-
subject.signal.should be_true
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
describe '#broadcast' do
|
|
24
|
-
it 'should return immediately' do
|
|
25
|
-
subject.broadcast.should be_true
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
context 'with one waiting thread' do
|
|
31
|
-
|
|
32
|
-
context 'signalled wake up' do
|
|
33
|
-
|
|
34
|
-
describe '#wait without timeout' do
|
|
35
|
-
|
|
36
|
-
it 'should block the thread' do
|
|
37
|
-
t = Thread.new { mutex.synchronize { subject.wait(mutex) } }
|
|
38
|
-
sleep(0.1)
|
|
39
|
-
t.status.should eq 'sleep'
|
|
40
|
-
t.kill
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
it 'should return a woken up result when is woken up by #signal' do
|
|
44
|
-
result = nil
|
|
45
|
-
t = Thread.new { mutex.synchronize { result = subject.wait(mutex) } }
|
|
46
|
-
sleep(0.1)
|
|
47
|
-
mutex.synchronize { subject.signal }
|
|
48
|
-
sleep(0.1)
|
|
49
|
-
result.should be_woken_up
|
|
50
|
-
result.should_not be_timed_out
|
|
51
|
-
result.remaining_time.should be_nil
|
|
52
|
-
t.status.should be_false
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
it 'should return a woken up result when is woken up by #broadcast' do
|
|
56
|
-
result = nil
|
|
57
|
-
t = Thread.new { mutex.synchronize { result = subject.wait(mutex) } }
|
|
58
|
-
sleep(0.1)
|
|
59
|
-
mutex.synchronize { subject.broadcast }
|
|
60
|
-
sleep(0.1)
|
|
61
|
-
result.should be_woken_up
|
|
62
|
-
result.should_not be_timed_out
|
|
63
|
-
result.remaining_time.should be_nil
|
|
64
|
-
t.status.should be_false
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
context 'timeout' do
|
|
71
|
-
|
|
72
|
-
describe '#wait' do
|
|
73
|
-
|
|
74
|
-
it 'should block the thread' do
|
|
75
|
-
t = Thread.new { mutex.synchronize { subject.wait(mutex, 1) } }
|
|
76
|
-
sleep(0.1)
|
|
77
|
-
t.status.should eq 'sleep'
|
|
78
|
-
t.kill
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
it 'should return remaining time when is woken up by #signal' do
|
|
82
|
-
result = nil
|
|
83
|
-
t = Thread.new { mutex.synchronize { result = subject.wait(mutex, 1) } }
|
|
84
|
-
sleep(0.1)
|
|
85
|
-
mutex.synchronize { subject.signal }
|
|
86
|
-
sleep(0.1)
|
|
87
|
-
result.should be_woken_up
|
|
88
|
-
result.should_not be_timed_out
|
|
89
|
-
result.remaining_time.should be_within(0.1).of(0.85)
|
|
90
|
-
t.status.should be_false
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
it 'should return remaining time when is woken up by #broadcast' do
|
|
94
|
-
result = nil
|
|
95
|
-
t = Thread.new { mutex.synchronize { result = subject.wait(mutex, 1) } }
|
|
96
|
-
sleep(0.1)
|
|
97
|
-
mutex.synchronize { subject.broadcast }
|
|
98
|
-
sleep(0.1)
|
|
99
|
-
result.should be_woken_up
|
|
100
|
-
result.should_not be_timed_out
|
|
101
|
-
result.remaining_time.should be_within(0.1).of(0.85)
|
|
102
|
-
t.status.should be_false
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
it 'should return 0 or negative number if timed out' do
|
|
106
|
-
result = nil
|
|
107
|
-
t = Thread.new { mutex.synchronize { result = subject.wait(mutex, 0.1) } }
|
|
108
|
-
sleep(0.2)
|
|
109
|
-
result.should_not be_woken_up
|
|
110
|
-
result.should be_timed_out
|
|
111
|
-
result.remaining_time.should be_less_than_or_equal_to(0)
|
|
112
|
-
t.status.should be_false
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
context 'with many waiting threads' do
|
|
120
|
-
|
|
121
|
-
context 'signalled wake up' do
|
|
122
|
-
|
|
123
|
-
describe '#wait' do
|
|
124
|
-
|
|
125
|
-
it 'should block threads' do
|
|
126
|
-
t1 = Thread.new { mutex.synchronize { subject.wait(mutex) } }
|
|
127
|
-
t2 = Thread.new { mutex.synchronize { subject.wait(mutex) } }
|
|
128
|
-
sleep(0.1)
|
|
129
|
-
[t1, t2].each { |t| t.status.should eq 'sleep' }
|
|
130
|
-
[t1, t2].each { |t| t.kill }
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
describe '#signal' do
|
|
136
|
-
it 'wakes up only one thread' do
|
|
137
|
-
latch = CountDownLatch.new(2)
|
|
138
|
-
|
|
139
|
-
t1 = Thread.new { mutex.synchronize { subject.wait(mutex); latch.count_down } }
|
|
140
|
-
t2 = Thread.new { mutex.synchronize { subject.wait(mutex); latch.count_down } }
|
|
141
|
-
|
|
142
|
-
sleep(0.1)
|
|
143
|
-
mutex.synchronize { subject.signal }
|
|
144
|
-
sleep(0.2)
|
|
145
|
-
|
|
146
|
-
latch.count.should eq 1
|
|
147
|
-
[t1, t2].each { |t| t.kill }
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
describe '#broadcast' do
|
|
152
|
-
it 'wakes up all threads' do
|
|
153
|
-
latch = CountDownLatch.new(2)
|
|
154
|
-
|
|
155
|
-
t1 = Thread.new { mutex.synchronize { subject.wait(mutex); latch.count_down } }
|
|
156
|
-
t2 = Thread.new { mutex.synchronize { subject.wait(mutex); latch.count_down } }
|
|
157
|
-
|
|
158
|
-
sleep(0.1)
|
|
159
|
-
mutex.synchronize { subject.broadcast }
|
|
160
|
-
sleep(0.2)
|
|
161
|
-
|
|
162
|
-
latch.count.should eq 0
|
|
163
|
-
[t1, t2].each { |t| t.kill }
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
end
|
|
171
|
-
end
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
share_examples_for :count_down_latch do
|
|
4
|
-
|
|
5
|
-
let(:latch) { described_class.new(3) }
|
|
6
|
-
let(:zero_count_latch) { described_class.new(0) }
|
|
7
|
-
|
|
8
|
-
context '#initialize' do
|
|
9
|
-
|
|
10
|
-
it 'raises an exception if the initial count is less than zero' do
|
|
11
|
-
expect {
|
|
12
|
-
described_class.new(-1)
|
|
13
|
-
}.to raise_error(ArgumentError)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it 'raises an exception if the initial count is not an integer' do
|
|
17
|
-
expect {
|
|
18
|
-
described_class.new('foo')
|
|
19
|
-
}.to raise_error(ArgumentError)
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
describe '#count' do
|
|
24
|
-
|
|
25
|
-
it 'should be the value passed to the constructor' do
|
|
26
|
-
latch.count.should eq 3
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it 'should be decreased after every count down' do
|
|
30
|
-
latch.count_down
|
|
31
|
-
latch.count.should eq 2
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
it 'should not go below zero' do
|
|
35
|
-
5.times { latch.count_down }
|
|
36
|
-
latch.count.should eq 0
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
describe '#wait' do
|
|
41
|
-
|
|
42
|
-
context 'count set to zero' do
|
|
43
|
-
it 'should return true immediately' do
|
|
44
|
-
result = zero_count_latch.wait
|
|
45
|
-
result.should be_true
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it 'should return true immediately with timeout' do
|
|
49
|
-
result = zero_count_latch.wait(5)
|
|
50
|
-
result.should be_true
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
context 'non zero count' do
|
|
55
|
-
|
|
56
|
-
it 'should block thread until counter is set to zero' do
|
|
57
|
-
3.times do
|
|
58
|
-
Thread.new { sleep(0.1); latch.count_down }
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
result = latch.wait
|
|
62
|
-
result.should be_true
|
|
63
|
-
latch.count.should eq 0
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
it 'should block until counter is set to zero with timeout' do
|
|
67
|
-
3.times do
|
|
68
|
-
Thread.new { sleep(0.1); latch.count_down }
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
result = latch.wait(1)
|
|
72
|
-
result.should be_true
|
|
73
|
-
latch.count.should eq 0
|
|
74
|
-
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
it 'should block until timeout and return false when counter is not set to zero' do
|
|
78
|
-
result = latch.wait(0.1)
|
|
79
|
-
result.should be_false
|
|
80
|
-
latch.count.should eq 3
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
module Concurrent
|
|
87
|
-
|
|
88
|
-
describe MutexCountDownLatch do
|
|
89
|
-
|
|
90
|
-
it_should_behave_like :count_down_latch
|
|
91
|
-
|
|
92
|
-
context 'spurious wake ups' do
|
|
93
|
-
|
|
94
|
-
subject { described_class.new(3) }
|
|
95
|
-
|
|
96
|
-
before(:each) do
|
|
97
|
-
def subject.simulate_spurious_wake_up
|
|
98
|
-
@mutex.synchronize do
|
|
99
|
-
@condition.signal
|
|
100
|
-
@condition.broadcast
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
it 'should resist to spurious wake ups without timeout' do
|
|
106
|
-
@expected = false
|
|
107
|
-
Thread.new { subject.wait; @expected = true }
|
|
108
|
-
|
|
109
|
-
sleep(0.1)
|
|
110
|
-
subject.simulate_spurious_wake_up
|
|
111
|
-
|
|
112
|
-
sleep(0.1)
|
|
113
|
-
@expected.should be_false
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
it 'should resist to spurious wake ups with timeout' do
|
|
117
|
-
@expected = false
|
|
118
|
-
Thread.new { subject.wait(0.5); @expected = true }
|
|
119
|
-
|
|
120
|
-
sleep(0.1)
|
|
121
|
-
subject.simulate_spurious_wake_up
|
|
122
|
-
|
|
123
|
-
sleep(0.1)
|
|
124
|
-
@expected.should be_false
|
|
125
|
-
|
|
126
|
-
sleep(0.4)
|
|
127
|
-
@expected.should be_true
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
if TestHelpers.jruby?
|
|
133
|
-
|
|
134
|
-
describe JavaCountDownLatch do
|
|
135
|
-
|
|
136
|
-
it_should_behave_like :count_down_latch
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
describe CountDownLatch do
|
|
141
|
-
if jruby?
|
|
142
|
-
it 'inherits from JavaCountDownLatch' do
|
|
143
|
-
CountDownLatch.ancestors.should include(JavaCountDownLatch)
|
|
144
|
-
end
|
|
145
|
-
else
|
|
146
|
-
it 'inherits from MutexCountDownLatch' do
|
|
147
|
-
CountDownLatch.ancestors.should include(MutexCountDownLatch)
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
end
|