From d1644104c8660281418ab0c98f460f9a3a1b1c64 Mon Sep 17 00:00:00 2001 From: Marc Siegel Date: Thu, 26 Dec 2013 12:27:36 -0500 Subject: [PATCH] On mach, allow other ruby green threads to continue during semaphore wait --- lib/mach/functions.rb | 7 ++++--- spec/process_shared/lock_behavior.rb | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/mach/functions.rb b/lib/mach/functions.rb index d5cd8e7..057ec38 100644 --- a/lib/mach/functions.rb +++ b/lib/mach/functions.rb @@ -72,8 +72,8 @@ module Mach # Attach a function as with +attach_function+, but check the # return value and raise an exception on errors. - def self.attach_mach_function(sym, argtypes, rettype) - attach_function(sym, argtypes, rettype) + def self.attach_mach_function(sym, argtypes, rettype, options = nil) + attach_function(sym, argtypes, rettype, options) error_check(sym) end @@ -208,7 +208,8 @@ module Mach :kern_return_t) attach_mach_function(:semaphore_wait, [:semaphore_t], - :kern_return_t) + :kern_return_t, + :blocking => true) attach_mach_function(:semaphore_timedwait, [:semaphore_t, TimeSpec.val], :kern_return_t) diff --git a/spec/process_shared/lock_behavior.rb b/spec/process_shared/lock_behavior.rb index 77f97bc..d45d742 100644 --- a/spec/process_shared/lock_behavior.rb +++ b/spec/process_shared/lock_behavior.rb @@ -55,6 +55,26 @@ module ProcessShared mem.get_char(0).must_equal(0) end + def test_allows_other_threads_within_a_process_to_continue_while_locked + was_set = false + + @lock.synchronize do + 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 + @lock.synchronize { } + end + + # t1 should set the flag and die while t2 is still waiting on the lock + t1.join + end + + was_set.must_equal(true) + end end end