@@ -58,14 +58,20 @@ module Concurrent
5858 barrier . reset
5959 barrier . broken? . should eq false
6060 end
61-
62- it 'should be broken when at least one thread timed out'
63- it 'should be restored when reset is called'
6461 end
6562
6663 describe 'reset' do
67- it 'should release all waiting threads'
68- it 'should not execute the block'
64+ it 'should release all waiting threads' do
65+ latch = CountDownLatch . new ( 1 )
66+
67+ Thread . new { barrier . wait ; latch . count_down }
68+ sleep ( 0.1 )
69+ barrier . reset
70+ latch . wait ( 0.1 ) . should be_true
71+
72+ barrier . should_not be_broken
73+ barrier . number_waiting . should eq 0
74+ end
6975 end
7076
7177 describe '#wait' do
@@ -83,6 +89,7 @@ module Concurrent
8389 parties . times { Thread . new { barrier . wait ; latch . count_down } }
8490 latch . wait ( 0.1 ) . should be_true
8591 barrier . number_waiting . should eq 0
92+ barrier . should_not be_broken
8693 end
8794
8895 it 'returns true when released' do
@@ -103,6 +110,16 @@ module Concurrent
103110
104111 counter . value . should eq 1
105112 end
113+
114+ it 'can be reused' do
115+ first_latch = CountDownLatch . new ( parties )
116+ parties . times { Thread . new { barrier . wait ; first_latch . count_down } }
117+ first_latch . wait ( 0.1 ) . should be_true
118+
119+ latch = CountDownLatch . new ( parties )
120+ parties . times { Thread . new { barrier . wait ; latch . count_down } }
121+ latch . wait ( 0.1 ) . should be_true
122+ end
106123 end
107124
108125 context 'with timeout' do
@@ -132,18 +149,91 @@ module Concurrent
132149
133150 context 'timeout expiring' do
134151
135- it 'returns false'
136- it 'can return early and break the barrier'
137- it 'does not execute the block on timeout'
152+ it 'returns false' do
153+ latch = CountDownLatch . new ( 1 )
154+
155+ Thread . new { latch . count_down if barrier . wait ( 0.1 ) == false }
156+ latch . wait ( 0.2 ) . should be_true
157+ end
158+
159+ it 'breaks the barrier and release all other threads' do
160+ latch = CountDownLatch . new ( 2 )
161+
162+ Thread . new { barrier . wait ( 0.1 ) ; latch . count_down }
163+ Thread . new { barrier . wait ; latch . count_down }
164+
165+ latch . wait ( 0.2 ) . should be_true
166+ barrier . should be_broken
167+ end
168+
169+ it 'does not execute the block on timeout' do
170+ counter = AtomicFixnum . new
171+ barrier = described_class . new ( parties ) { counter . increment }
172+
173+ barrier . wait ( 0.1 )
174+
175+ counter . value . should eq 0
176+ end
138177 end
139178 end
140- end
141179
142- context 'spurious wakeups' do
143- it 'should resist'
180+ context '#broken barrier' do
181+ it 'should not accept new threads' do
182+ Thread . new { barrier . wait ( 0.1 ) }
183+ sleep ( 0.2 )
184+
185+ barrier . should be_broken
186+
187+ barrier . wait . should be_false
188+ end
189+
190+ it 'can be reset' do
191+ Thread . new { barrier . wait ( 0.1 ) }
192+ sleep ( 0.2 )
193+
194+ barrier . should be_broken
195+
196+ barrier . reset
197+
198+ barrier . should_not be_broken
199+ end
200+ end
144201 end
145202
146- end
203+ context 'spurious wake ups' do
204+
205+ before ( :each ) do
206+ def barrier . simulate_spurious_wake_up
207+ @mutex . synchronize do
208+ @condition . signal
209+ @condition . broadcast
210+ end
211+ end
212+ end
213+
214+ it 'should resist to spurious wake ups without timeout' do
215+ @expected = false
216+ Thread . new { barrier . wait ; @expected = true }
217+
218+ sleep ( 0.1 )
219+ barrier . simulate_spurious_wake_up
220+
221+ sleep ( 0.1 )
222+ @expected . should be_false
223+ end
147224
225+ it 'should resist to spurious wake ups with timeout' do
226+ @expected = false
227+ Thread . new { barrier . wait ( 0.5 ) ; @expected = true }
228+
229+ sleep ( 0.1 )
230+ barrier . simulate_spurious_wake_up
231+
232+ sleep ( 0.1 )
233+ @expected . should be_false
234+
235+ end
236+ end
237+ end
148238
149239end
0 commit comments