@@ -58,14 +58,20 @@ module Concurrent
58
58
barrier . reset
59
59
barrier . broken? . should eq false
60
60
end
61
-
62
- it 'should be broken when at least one thread timed out'
63
- it 'should be restored when reset is called'
64
61
end
65
62
66
63
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
69
75
end
70
76
71
77
describe '#wait' do
@@ -83,6 +89,7 @@ module Concurrent
83
89
parties . times { Thread . new { barrier . wait ; latch . count_down } }
84
90
latch . wait ( 0.1 ) . should be_true
85
91
barrier . number_waiting . should eq 0
92
+ barrier . should_not be_broken
86
93
end
87
94
88
95
it 'returns true when released' do
@@ -103,6 +110,16 @@ module Concurrent
103
110
104
111
counter . value . should eq 1
105
112
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
106
123
end
107
124
108
125
context 'with timeout' do
@@ -132,18 +149,91 @@ module Concurrent
132
149
133
150
context 'timeout expiring' do
134
151
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
138
177
end
139
178
end
140
- end
141
179
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
144
201
end
145
202
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
147
224
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
148
238
149
239
end
0 commit comments