Class: Concurrent::CyclicBarrier

Inherits:
Synchronization::LockableObject
  • Object
show all
Defined in:
lib/concurrent/atomic/cyclic_barrier.rb

Overview

A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.

Instance Method Summary collapse

Constructor Details

#initialize(parties) { ... } ⇒ CyclicBarrier

Create a new ‘CyclicBarrier` that waits for `parties` threads

Yields:

  • an optional block that will be executed that will be executed after the last thread arrives and before the others are released

Raises:

  • (ArgumentError)

    if ‘parties` is not an integer or is less than zero



20
21
22
23
24
25
26
# File 'lib/concurrent/atomic/cyclic_barrier.rb', line 20

def initialize(parties, &block)
  if !parties.is_a?(Fixnum) || parties < 1
    raise ArgumentError.new('count must be in integer greater than or equal zero')
  end
  super(&nil)
  synchronize { ns_initialize parties, &block }
end

Instance Method Details

#broken?Boolean

A barrier can be broken when:

  • a thread called the ‘reset` method while at least one other thread was waiting

  • at least one thread timed out on ‘wait` method

A broken barrier can be restored using ‘reset` it’s safer to create a new one



85
86
87
# File 'lib/concurrent/atomic/cyclic_barrier.rb', line 85

def broken?
  synchronize { @generation.status != :waiting }
end

#number_waitingFixnum



34
35
36
# File 'lib/concurrent/atomic/cyclic_barrier.rb', line 34

def number_waiting
  synchronize { @number_waiting }
end

#partiesFixnum



29
30
31
# File 'lib/concurrent/atomic/cyclic_barrier.rb', line 29

def parties
  synchronize { @parties }
end

#resetnil

resets the barrier to its initial state If there is at least one waiting thread, it will be woken up, the ‘wait` method will return false and the barrier will be broken If the barrier is broken, this method restores it to the original state



75
76
77
# File 'lib/concurrent/atomic/cyclic_barrier.rb', line 75

def reset
  synchronize { ns_generation_done @generation, :reset }
end

#wait(timeout = nil) ⇒ Boolean

Blocks on the barrier until the number of waiting threads is equal to ‘parties` or until `timeout` is reached or `reset` is called If a block has been passed to the constructor, it will be executed once by

the last arrived thread before releasing the others


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/concurrent/atomic/cyclic_barrier.rb', line 46

def wait(timeout = nil)
  synchronize do

    return false unless @generation.status == :waiting

    @number_waiting += 1

    if @number_waiting == @parties
      @action.call if @action
      ns_generation_done @generation, :fulfilled
      true
    else
      generation = @generation
      if ns_wait_until(timeout) { generation.status != :waiting }
        generation.status == :fulfilled
      else
        ns_generation_done generation, :broken, false
        false
      end
    end
  end
end