class Concurrent::MutexSemaphore

@!macro internal_implementation_note
@!visibility private
@!macro semaphore

def acquire(permits = 1)

@!macro semaphore_method_acquire
def acquire(permits = 1)
  Utility::NativeInteger.ensure_integer_and_bounds permits
  Utility::NativeInteger.ensure_positive permits
  synchronize do
    try_acquire_timed(permits, nil)
  end
  return unless block_given?
  begin
    yield
  ensure
    release(permits)
  end
end

def available_permits

@!macro semaphore_method_available_permits
def available_permits
  synchronize { @free }
end

def drain_permits

Returns:
  • (Integer) -
def drain_permits
  synchronize do
    @free.tap { |_| @free = 0 }
  end
end

def initialize(count)

@!macro semaphore_method_initialize
def initialize(count)
  Utility::NativeInteger.ensure_integer_and_bounds count
  super()
  synchronize { ns_initialize count }
end

def ns_initialize(count)

@!visibility private
def ns_initialize(count)
  @free = count
end

def reduce_permits(reduction)

Returns:
  • (nil) -

Raises:
  • (ArgumentError) - if `@free` - `@reduction` is less than zero
  • (ArgumentError) - if `reduction` is not an integer or is negative

Parameters:
  • reduction (Fixnum) -- Number of permits to remove.
def reduce_permits(reduction)
  Utility::NativeInteger.ensure_integer_and_bounds reduction
  Utility::NativeInteger.ensure_positive reduction
  synchronize { @free -= reduction }
  nil
end

def release(permits = 1)

@!macro semaphore_method_release
def release(permits = 1)
  Utility::NativeInteger.ensure_integer_and_bounds permits
  Utility::NativeInteger.ensure_positive permits
  synchronize do
    @free += permits
    permits.times { ns_signal }
  end
  nil
end

def try_acquire(permits = 1, timeout = nil)

@!macro semaphore_method_try_acquire
def try_acquire(permits = 1, timeout = nil)
  Utility::NativeInteger.ensure_integer_and_bounds permits
  Utility::NativeInteger.ensure_positive permits
  acquired = synchronize do
    if timeout.nil?
      try_acquire_now(permits)
    else
      try_acquire_timed(permits, timeout)
    end
  end
  return acquired unless block_given?
  return unless acquired
  begin
    yield
  ensure
    release(permits)
  end
end

def try_acquire_now(permits)

@!visibility private
def try_acquire_now(permits)
  if @free >= permits
    @free -= permits
    true
  else
    false
  end
end

def try_acquire_timed(permits, timeout)

@!visibility private
def try_acquire_timed(permits, timeout)
  ns_wait_until(timeout) { try_acquire_now(permits) }
end