Fix ConditionVariable#signal to only post if semaphore has waiters

This fixes a bug where calls to #signal would end up "over-posting"
the semaphore, causing subsequent waits to return immediately until
the semaphore value is back down to zero.
This commit is contained in:
Marc Siegel 2013-12-27 15:15:07 -05:00
parent dddf0be4ef
commit 4518e6fdad
2 changed files with 17 additions and 1 deletions

View File

@ -16,7 +16,9 @@ module ProcessShared
end end
def signal def signal
@sem.post @internal.synchronize do
@sem.post unless @waiting.read_int.zero?
end
end end
def wait(mutex, timeout = nil) def wait(mutex, timeout = nil)

View File

@ -63,5 +63,19 @@ module ProcessShared
(Time.now.to_f - start).must be_gte(0.1) (Time.now.to_f - start).must be_gte(0.1)
} }
end end
it 'correctly handles #signal when no waiters' do
mutex = Mutex.new
cond = ConditionVariable.new
# fix for bug: #wait not waiting after unmatched call to #signal
cond.signal
mutex.synchronize {
start = Time.now.to_f
cond.wait(mutex, 0.1)
(Time.now.to_f - start).must be_gte(0.1)
}
end
end end
end end