2012-01-15 14:02:53 +00:00
|
|
|
require 'mach/functions'
|
|
|
|
require 'mach/port'
|
2012-02-02 03:34:51 +00:00
|
|
|
require 'mach/host'
|
|
|
|
require 'mach/clock'
|
2012-01-15 14:02:53 +00:00
|
|
|
|
|
|
|
module Mach
|
|
|
|
class Semaphore < Port
|
|
|
|
include Functions
|
|
|
|
|
|
|
|
# Create a new Semaphore.
|
|
|
|
#
|
|
|
|
# @param [Hash] opts
|
|
|
|
#
|
2012-01-16 14:14:58 +00:00
|
|
|
# @option opts [Integer] :value the initial value of the
|
|
|
|
# semaphore; defaults to 1
|
|
|
|
#
|
2012-01-15 14:02:53 +00:00
|
|
|
# @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)
|
|
|
|
#
|
2012-01-16 14:14:58 +00:00
|
|
|
# @options opts [Integer] :port existing port to wrap with a
|
|
|
|
# Semaphore object; otherwise a new semaphore is created
|
|
|
|
#
|
2012-01-15 14:02:53 +00:00
|
|
|
# @return [Integer] a semaphore port name
|
2012-01-16 14:14:58 +00:00
|
|
|
def initialize(opts = {})
|
|
|
|
value = opts[:value] || 1
|
2012-01-21 21:06:46 +00:00
|
|
|
task = (opts[:task] && opts[:task].to_i) || ipc_space || mach_task_self
|
2012-01-15 14:02:53 +00:00
|
|
|
sync_policy = opts[:sync_policy] || :fifo
|
|
|
|
|
2012-01-16 14:14:58 +00:00
|
|
|
port = if opts[:port]
|
2012-01-21 21:06:46 +00:00
|
|
|
opts[:port].to_i
|
2012-01-16 14:14:58 +00:00
|
|
|
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)
|
2012-01-15 14:02:53 +00:00
|
|
|
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
|
2012-01-21 21:06:46 +00:00
|
|
|
semaphore_destroy(task.to_i, port)
|
2012-01-15 14:02:53 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def signal
|
|
|
|
semaphore_signal(port)
|
|
|
|
end
|
|
|
|
|
|
|
|
def signal_all
|
|
|
|
semaphore_signal_all(port)
|
|
|
|
end
|
|
|
|
|
|
|
|
def wait
|
|
|
|
semaphore_wait(port)
|
|
|
|
end
|
|
|
|
|
2012-02-02 03:34:51 +00:00
|
|
|
# @see http://pkaudio.blogspot.com/2010/05/mac-os-x-no-timed-semaphore-waits.html
|
2012-01-15 14:02:53 +00:00
|
|
|
def timedwait(secs)
|
2012-02-02 03:34:51 +00:00
|
|
|
timespec = TimeSpec.new
|
|
|
|
timespec.add_seconds!(secs)
|
|
|
|
|
2012-01-15 14:02:53 +00:00
|
|
|
semaphore_timedwait(port, timespec)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|