71 lines
1.7 KiB
Ruby
71 lines
1.7 KiB
Ruby
require 'spec_helper'
|
|
require 'mach'
|
|
|
|
module Mach
|
|
describe 'low level semaphore functions' do
|
|
include Functions
|
|
|
|
it 'raises exception with invalid args' do
|
|
p = proc { semaphore_create(mach_task_self, nil, 1234, 1) }
|
|
p.must_raise Error::INVALID_ARGUMENT
|
|
end
|
|
end
|
|
|
|
describe Semaphore do
|
|
it 'creates a semaphore' do
|
|
sem = Semaphore.new
|
|
sem.destroy
|
|
end
|
|
|
|
it 'raises exception with invalid args' do
|
|
p = proc { Semaphore.new(:sync_policy => :no_such) }
|
|
p.must_raise ArgumentError # Error::INVALID_ARGUMENT
|
|
end
|
|
|
|
it 'signals/waits in same task' do
|
|
sem = Semaphore.new(:value => 0)
|
|
sem.signal
|
|
sem.wait
|
|
sem.destroy
|
|
end
|
|
|
|
it 'coordinates access to shared resource between two tasks' do
|
|
begin
|
|
sem = Semaphore.new(:value => 0)
|
|
|
|
port = Port.new
|
|
port.insert_right(:make_send)
|
|
Task.self.set_bootstrap_port(port)
|
|
|
|
method = if Process.respond_to?(:__mach_original_fork__)
|
|
:__mach_original_fork__
|
|
else
|
|
:fork
|
|
end
|
|
|
|
child = Process.send(method) do
|
|
parent_port = Task.self.get_bootstrap_port
|
|
Task.self.copy_send(parent_port)
|
|
# parent will copy send rights to sem into child task
|
|
sleep 0.5
|
|
sem.signal
|
|
Kernel.exit!
|
|
end
|
|
|
|
child_task_port = port.receive_right
|
|
|
|
start = Time.now.to_f
|
|
sem.insert_right(:copy_send, :ipc_space => child_task_port)
|
|
sem.timedwait(1)
|
|
elapsed = Time.now.to_f - start
|
|
|
|
Process.wait child
|
|
|
|
elapsed.must be_gt(0.4)
|
|
ensure
|
|
Task.self.set_bootstrap_port(Mach::Functions.bootstrap_port)
|
|
end
|
|
end
|
|
end
|
|
end
|