diff --git a/lib/mach/functions.rb b/lib/mach/functions.rb index 057ec38..eda7628 100644 --- a/lib/mach/functions.rb +++ b/lib/mach/functions.rb @@ -212,7 +212,8 @@ module Mach :blocking => true) attach_mach_function(:semaphore_timedwait, [:semaphore_t, TimeSpec.val], - :kern_return_t) + :kern_return_t, + :blocking => true) end end diff --git a/spec/process_shared/semaphore_spec.rb b/spec/process_shared/semaphore_spec.rb index c6afad1..a39f959 100644 --- a/spec/process_shared/semaphore_spec.rb +++ b/spec/process_shared/semaphore_spec.rb @@ -131,6 +131,31 @@ module ProcessShared ::Process.wait(pid) end end + + it 'allows other threads in a process to continue while waiting' do + # NOTE: A similar test in LockBehavior tests Semaphore#wait, + # Mutex#lock, etc. Necessary only to test #try_wait here. + + start = Time.now.to_f + was_set = false + + Semaphore.open(0) do |sem| + t1 = Thread.new do + # give t2 a chance to wait on the lock, then set the flag + sleep 0.01 + was_set = true + end + + t2 = Thread.new do + sem.try_wait(10.0) + end + + t1.join + end + + was_set.must_equal true + (Time.now.to_f - start).must be_lt(0.1) + end end end end