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
 |