Class: Concurrent::MutexSemaphore

Inherits:
Object
  • Object
show all
Defined in:
lib/concurrent/atomic/semaphore.rb

Direct Known Subclasses

Semaphore

Instance Method Summary collapse

Constructor Details

#initialize(count) ⇒ MutexSemaphore

Create a new ‘Semaphore` with the initial `count`.

Parameters:

  • count (Fixnum)

    the initial count

Raises:

  • (ArgumentError)

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



12
13
14
15
16
17
18
19
# File 'lib/concurrent/atomic/semaphore.rb', line 12

def initialize(count)
  unless count.is_a?(Fixnum) && count >= 0
    fail ArgumentError, 'count must be an non-negative integer'
  end
  @mutex = Mutex.new
  @condition = Condition.new
  @free = count
end

Instance Method Details

#acquire(permits = 1) ⇒ Nil

Acquires the given number of permits from this semaphore,

blocking until all are available.

Parameters:

  • permits (Fixnum) (defaults to: 1)

    Number of permits to acquire

Returns:

  • (Nil)

Raises:

  • (ArgumentError)

    if ‘permits` is not an integer or is less than one



32
33
34
35
36
37
38
39
40
# File 'lib/concurrent/atomic/semaphore.rb', line 32

def acquire(permits = 1)
  unless permits.is_a?(Fixnum) && permits > 0
    fail ArgumentError, 'permits must be an integer greater than zero'
  end
  @mutex.synchronize do
    try_acquire_timed(permits, nil)
    nil
  end
end

#available_permitsInteger

Returns the current number of permits available in this semaphore.

Returns:

  • (Integer)


47
48
49
# File 'lib/concurrent/atomic/semaphore.rb', line 47

def available_permits
  @mutex.synchronize { @free }
end

#drain_permitsInteger

Acquires and returns all permits that are immediately available.

Returns:

  • (Integer)


56
57
58
59
60
# File 'lib/concurrent/atomic/semaphore.rb', line 56

def drain_permits
  @mutex.synchronize do
    @free.tap { |_| @free = 0 }
  end
end

#reduce_permits(reduction) ⇒ Nil

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Shrinks the number of available permits by the indicated reduction.

Parameters:

  • reduction (Fixnum)

    Number of permits to remove.

Returns:

  • (Nil)

Raises:

  • (ArgumentError)

    if ‘reduction` is not an integer or is negative

  • (ArgumentError)

    if ‘@free` - `@reduction` is less than zero



124
125
126
127
128
129
130
# File 'lib/concurrent/atomic/semaphore.rb', line 124

def reduce_permits(reduction)
  unless reduction.is_a?(Fixnum) && reduction >= 0
    fail ArgumentError, 'reduction must be an non-negative integer'
  end
  @mutex.synchronize { @free -= reduction }
  nil 
end

#release(permits = 1) ⇒ Nil

Releases the given number of permits, returning them to the semaphore.

Parameters:

  • permits (Fixnum) (defaults to: 1)

    Number of permits to return to the semaphore.

Returns:

  • (Nil)

Raises:

  • (ArgumentError)

    if ‘permits` is not a number or is less than one



100
101
102
103
104
105
106
107
108
109
# File 'lib/concurrent/atomic/semaphore.rb', line 100

def release(permits = 1)
  unless permits.is_a?(Fixnum) && permits > 0
    fail ArgumentError, 'permits must be an integer greater than zero'
  end
  @mutex.synchronize do
    @free += permits
    permits.times { @condition.signal }
  end
  nil
end

#try_acquire(permits = 1, timeout = nil) ⇒ Boolean

Acquires the given number of permits from this semaphore,

only if all are available at the time of invocation or within
`timeout` interval

Parameters:

  • permits (Fixnum) (defaults to: 1)

    the number of permits to acquire

  • timeout (Fixnum) (defaults to: nil)

    the number of seconds to wait for the counter or ‘nil` to return immediately

Returns:

  • (Boolean)

    ‘false` if no permits are available, `true` when acquired a permit

Raises:

  • (ArgumentError)

    if ‘permits` is not an integer or is less than one



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/concurrent/atomic/semaphore.rb', line 78

def try_acquire(permits = 1, timeout = nil)
  unless permits.is_a?(Fixnum) && permits > 0
    fail ArgumentError, 'permits must be an integer greater than zero'
  end
  @mutex.synchronize do
    if timeout.nil?
      try_acquire_now(permits)
    else
      try_acquire_timed(permits, timeout)
    end
  end
end