Skip to content

Commit 662ba4a

Browse files
committed
Migrate CyclicBarrier to SynchronizedObject
1 parent 3a8aedc commit 662ba4a

File tree

2 files changed

+25
-32
lines changed

2 files changed

+25
-32
lines changed
Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
require 'concurrent/synchronized_object'
2+
13
module Concurrent
24

3-
class CyclicBarrier
5+
class CyclicBarrier < SynchronizedObject
46

57
Generation = Struct.new(:status)
68
private_constant :Generation
@@ -13,23 +15,26 @@ class CyclicBarrier
1315
#
1416
# @raise [ArgumentError] if `parties` is not an integer or is less than zero
1517
def initialize(parties, &block)
16-
raise ArgumentError.new('count must be in integer greater than or equal zero') if !parties.is_a?(Fixnum) || parties < 1
17-
@parties = parties
18-
@mutex = Mutex.new
19-
@condition = Condition.new
20-
@number_waiting = 0
21-
@action = block
22-
@generation = Generation.new(:waiting)
18+
super(&nil)
19+
if !parties.is_a?(Fixnum) || parties < 1
20+
raise ArgumentError.new('count must be in integer greater than or equal zero')
21+
end
22+
synchronize do
23+
@parties = parties
24+
@number_waiting = 0
25+
@action = block
26+
@generation = Generation.new(:waiting)
27+
end
2328
end
2429

2530
# @return [Fixnum] the number of threads needed to pass the barrier
2631
def parties
27-
@parties
32+
synchronize { @parties }
2833
end
2934

3035
# @return [Fixnum] the number of threads currently waiting on the barrier
3136
def number_waiting
32-
@number_waiting
37+
synchronize { @number_waiting }
3338
end
3439

3540
# Blocks on the barrier until the number of waiting threads is equal to
@@ -41,7 +46,7 @@ def number_waiting
4146
# @return [Boolean] `true` if the `count` reaches zero else false on
4247
# `timeout` or on `reset` or if the barrier is broken
4348
def wait(timeout = nil)
44-
@mutex.synchronize do
49+
synchronize do
4550

4651
return false unless @generation.status == :waiting
4752

@@ -58,17 +63,14 @@ def wait(timeout = nil)
5863
end
5964

6065

61-
6266
# resets the barrier to its initial state
6367
# If there is at least one waiting thread, it will be woken up, the `wait`
6468
# method will return false and the barrier will be broken
6569
# If the barrier is broken, this method restores it to the original state
6670
#
6771
# @return [nil]
6872
def reset
69-
@mutex.synchronize do
70-
set_status_and_restore(:reset)
71-
end
73+
synchronize { set_status_and_restore(:reset) }
7274
end
7375

7476
# A barrier can be broken when:
@@ -78,35 +80,26 @@ def reset
7880
# A broken barrier can be restored using `reset` it's safer to create a new one
7981
# @return [Boolean] true if the barrier is broken otherwise false
8082
def broken?
81-
@mutex.synchronize { @generation.status != :waiting }
83+
synchronize { @generation.status != :waiting }
8284
end
8385

8486
private
8587

8688
def set_status_and_restore(new_status)
8789
@generation.status = new_status
88-
@condition.broadcast
89-
@generation = Generation.new(:waiting)
90+
ns_broadcast
91+
@generation = Generation.new(:waiting)
9092
@number_waiting = 0
9193
end
9294

9395
def wait_for_wake_up(generation, timeout)
94-
if wait_while_waiting(generation, timeout)
96+
if ns_wait_until(timeout) { generation.status != :waiting }
9597
generation.status == :fulfilled
9698
else
9799
generation.status = :broken
98-
@condition.broadcast
100+
ns_broadcast
99101
false
100102
end
101103
end
102-
103-
def wait_while_waiting(generation, timeout)
104-
remaining = Condition::Result.new(timeout)
105-
while generation.status == :waiting && remaining.can_wait?
106-
remaining = @condition.wait(@mutex, remaining.remaining_time)
107-
end
108-
remaining.woken_up?
109-
end
110-
111104
end
112105
end

spec/concurrent/atomic/cyclic_barrier_spec.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,9 @@ module Concurrent
211211

212212
before(:each) do
213213
def barrier.simulate_spurious_wake_up
214-
@mutex.synchronize do
215-
@condition.signal
216-
@condition.broadcast
214+
synchronize do
215+
ns_signal
216+
ns_broadcast
217217
end
218218
end
219219
end

0 commit comments

Comments
 (0)