Class: ProcessShared::Semaphore

Inherits:
AbstractSemaphore show all
Defined in:
lib/process_shared/semaphore.rb

Direct Known Subclasses

BinarySemaphore, BoundedSemaphore

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from AbstractSemaphore

gen_name, make_finalizer, #synchronize

Methods included from PSem

psem_error_check

Methods included from DefineSingletonMethod

#define_singleton_method

Methods included from WithSelf

#with_self

Constructor Details

#initialize(value = 1, name = nil) ⇒ Semaphore

Create a new semaphore with initial value value. After Kernel#fork, the semaphore will be shared across two (or more) processes. The semaphore must be closed with #close in each process that no longer needs the semaphore.

(An object finalizer is registered that will close the semaphore to avoid memory leaks, but this should be considered a last resort).

Parameters:

  • value (Integer) (defaults to: 1)

    the initial semaphore value

  • name (String) (defaults to: nil)

    not currently supported



29
30
31
32
33
# File 'lib/process_shared/semaphore.rb', line 29

def initialize(value = 1, name = nil)
  init(PSem.sizeof_psem_t, 'psem', name) do |sem_name|
    psem_open(sem, sem_name, value, err)
  end
end

Class Method Details

.open(value = 1, name = nil, &block) ⇒ Object

With no associated block, open is a synonym for Semaphore.new. If the optional code block is given, it will be passed sem as an argument, and the Semaphore object will automatically be closed when the block terminates. In this instance, Semaphore.open returns the value of the block.

Parameters:

  • value (Integer) (defaults to: 1)

    the initial semaphore value

  • name (String) (defaults to: nil)

    not currently supported



14
15
16
# File 'lib/process_shared/semaphore.rb', line 14

def self.open(value = 1, name = nil, &block)
  new(value, name).with_self(&block)
end

Instance Method Details

#closeObject

Release the resources associated with this semaphore. Calls to other methods are undefined after #close has been called.

Close must be called when the semaphore is no longer needed. An object finalizer will close the semaphore as a last resort.



80
81
82
# File 'lib/process_shared/semaphore.rb', line 80

def close
  psem_close(sem, err)
end

#postObject

Increment the value of the semaphore. If other processes are waiting on this semaphore, one will be woken.



61
62
63
# File 'lib/process_shared/semaphore.rb', line 61

def post
  psem_post(sem, err)
end

#try_wait(timeout = nil) ⇒ Object

Decrement the value of the semaphore if it can be done immediately (i.e. if it was non-zero). Otherwise, wait up to timeout seconds until another process increments via #post.

decremented immediately, raise Errno::EAGAIN. If timeout passed before the semaphore could be decremented, raise Errno::ETIMEDOUT.

Parameters:

  • timeout (Numeric) (defaults to: nil)

    the maximum seconds to wait, or nil to not wait

Returns:

  • If timeout is nil and the semaphore cannot be



51
52
53
54
55
56
57
# File 'lib/process_shared/semaphore.rb', line 51

def try_wait(timeout = nil)
  if timeout
    psem_timedwait(sem, timeout, err)
  else
    psem_trywait(sem, err)
  end
end

#valueInteger

Get the current value of the semaphore. Raises Errno::NOTSUP on platforms that don’t support this (e.g. Mac OS X).

Returns:

  • (Integer)

    the current value of the semaphore.



69
70
71
72
73
# File 'lib/process_shared/semaphore.rb', line 69

def value
  int = FFI::MemoryPointer.new(:int)
  psem_getvalue(sem, int, err)
  int.get_int(0)
end

#waitObject

Decrement the value of the semaphore. If the value is zero, wait until another process increments via #post.



37
38
39
# File 'lib/process_shared/semaphore.rb', line 37

def wait
  psem_wait(sem, err)
end