Move with_self open-with-block helper to common module from posix semaphore implementation.
This commit is contained in:
parent
63d10c12a2
commit
71aa552213
|
@ -1,8 +1,9 @@
|
|||
require 'process_shared/semaphore'
|
||||
|
||||
require 'process_shared/posix/errno'
|
||||
require 'process_shared/posix/libc'
|
||||
require 'process_shared/posix/time_val'
|
||||
require 'process_shared/posix/time_spec'
|
||||
require 'process_shared/with_self'
|
||||
|
||||
module ProcessShared
|
||||
module Posix
|
||||
|
@ -34,7 +35,7 @@ module ProcessShared
|
|||
end
|
||||
|
||||
include Foreign
|
||||
include ProcessShared::WithSelf
|
||||
include ProcessShared::Semaphore
|
||||
|
||||
# Make a Proc suitable for use as a finalizer that will call
|
||||
# +shm_unlink+ on +sem+.
|
||||
|
@ -44,17 +45,6 @@ module ProcessShared
|
|||
proc { LibC.shm_unlink(sem) }
|
||||
end
|
||||
|
||||
# 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.
|
||||
#
|
||||
# @param [Integer] value the initial semaphore value
|
||||
def self.open(value = 1, &block)
|
||||
new(value).with_self(&block)
|
||||
end
|
||||
|
||||
# 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
|
||||
|
|
|
@ -1,84 +1,37 @@
|
|||
require 'process_shared/psem'
|
||||
require 'process_shared/abstract_semaphore'
|
||||
require 'process_shared/with_self'
|
||||
|
||||
module ProcessShared
|
||||
class Semaphore < AbstractSemaphore
|
||||
# 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.
|
||||
#
|
||||
# @param [Integer] value the initial semaphore value
|
||||
# @param [String] name not currently supported
|
||||
def self.open(value = 1, name = nil, &block)
|
||||
new(value, name).with_self(&block)
|
||||
end
|
||||
module Semaphore
|
||||
include ProcessShared::WithSelf
|
||||
|
||||
# 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).
|
||||
#
|
||||
# @param [Integer] value the initial semaphore value
|
||||
# @param [String] name not currently supported
|
||||
def initialize(value = 1, name = nil)
|
||||
init(PSem.sizeof_psem_t, 'psem', name) do |sem_name|
|
||||
psem_open(sem, sem_name, value, err)
|
||||
class << self
|
||||
# the implementation to use to create semaphores. impl is set
|
||||
# based on the platform in 'process_shared'
|
||||
attr_accessor :impl
|
||||
|
||||
def new(*args)
|
||||
impl.new(*args)
|
||||
end
|
||||
|
||||
# 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.
|
||||
#
|
||||
# @param [Integer] value the initial semaphore value
|
||||
def open(value = 1, &block)
|
||||
new(value).with_self(&block)
|
||||
end
|
||||
end
|
||||
|
||||
# Decrement the value of the semaphore. If the value is zero,
|
||||
# wait until another process increments via {#post}.
|
||||
def wait
|
||||
psem_wait(sem, err)
|
||||
end
|
||||
|
||||
# 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}.
|
||||
#
|
||||
# @param timeout [Numeric] the maximum seconds to wait, or nil to not wait
|
||||
#
|
||||
# @return If +timeout+ is nil and the semaphore cannot be
|
||||
# decremented immediately, raise Errno::EAGAIN. If +timeout+
|
||||
# passed before the semaphore could be decremented, raise
|
||||
# Errno::ETIMEDOUT.
|
||||
def try_wait(timeout = nil)
|
||||
if timeout
|
||||
psem_timedwait(sem, timeout, err)
|
||||
else
|
||||
psem_trywait(sem, err)
|
||||
def synchronize
|
||||
wait
|
||||
begin
|
||||
yield
|
||||
ensure
|
||||
post
|
||||
end
|
||||
end
|
||||
|
||||
# Increment the value of the semaphore. If other processes are
|
||||
# waiting on this semaphore, one will be woken.
|
||||
def post
|
||||
psem_post(sem, err)
|
||||
end
|
||||
|
||||
# Get the current value of the semaphore. Raises {Errno::NOTSUP} on
|
||||
# platforms that don't support this (e.g. Mac OS X).
|
||||
#
|
||||
# @return [Integer] the current value of the semaphore.
|
||||
def value
|
||||
int = FFI::MemoryPointer.new(:int)
|
||||
psem_getvalue(sem, int, err)
|
||||
int.get_int(0)
|
||||
end
|
||||
|
||||
# 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.
|
||||
def close
|
||||
psem_close(sem, err)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue