75 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			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
 |