process_shared/lib/mach/semaphore.rb

75 lines
1.9 KiB
Ruby

require 'mach/functions'
require 'mach/port'
require 'mach/host'
require 'mach/clock'
module Mach
class Semaphore < Port
include Functions
# Create a new Semaphore.
#
# @param [Hash] opts
#
# @option opts [Integer] :value the initial value of the
# semaphore; defaults to 1
#
# @option opts [Integer] :task the Mach task that owns the
# semaphore (defaults to Mach.task_self)
#
# @options opts [Integer] :sync_policy the sync policy for this
# semaphore (defaults to SyncPolicy::FIFO)
#
# @options opts [Integer] :port existing port to wrap with a
# Semaphore object; otherwise a new semaphore is created
#
# @return [Integer] a semaphore port name
def initialize(opts = {})
value = opts[:value] || 1
task = (opts[:task] && opts[:task].to_i) || ipc_space || mach_task_self
sync_policy = opts[:sync_policy] || :fifo
port = if opts[:port]
opts[:port].to_i
else
mem = new_memory_pointer(:semaphore_t)
semaphore_create(task, mem, sync_policy, value)
mem.get_uint(0)
end
super(:port => port, :ipc_space => task)
end
# Destroy a Semaphore.
#
# @param [Hash] opts
#
# @option opts [Integer] :task the Mach task that owns the
# semaphore (defaults to the owning task)
def destroy(opts = {})
task = opts[:task] || ipc_space || mach_task_self
semaphore_destroy(task.to_i, port)
end
def signal
semaphore_signal(port)
end
def signal_all
semaphore_signal_all(port)
end
def wait
semaphore_wait(port)
end
# @see http://pkaudio.blogspot.com/2010/05/mac-os-x-no-timed-semaphore-waits.html
def timedwait(secs)
timespec = TimeSpec.new
timespec.add_seconds!(secs)
semaphore_timedwait(port, timespec)
end
end
end