Commit 51e3bb92 authored by Michael Hanselmann's avatar Michael Hanselmann

Fix long-standing race condition bug in locking unittest

Every once in a while we saw failures in the locking unittest, but
weren't able to determine the cause. This patch fixes it by using
threading.Event instead of plain threading.Condition to notify another
thread. In most cases, threading.Condition must be used with another
variable to keep the actual state.  threading.Event does this for us.
Otherwise it can happen that the waiter only gets the lock after
condition was notified.
Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent db169865
......@@ -604,7 +604,7 @@ class TestSharedLock(_ThreadedTestCase):
@_Repeat
def testMixedAcquireTimeout(self):
sync = threading.Condition()
sync = threading.Event()
def _AcquireShared(ev):
if not self.sl.acquire(shared=1, timeout=None):
......@@ -615,12 +615,8 @@ class TestSharedLock(_ThreadedTestCase):
# Notify main thread
ev.set()
# Wait for notification
sync.acquire()
try:
sync.wait()
finally:
sync.release()
# Wait for notification from main thread
sync.wait()
# Release lock
self.sl.release()
......@@ -641,7 +637,7 @@ class TestSharedLock(_ThreadedTestCase):
self.failIf(self.sl.acquire(shared=0, timeout=0.02))
# Acquire exclusive without timeout
exclsync = threading.Condition()
exclsync = threading.Event()
exclev = threading.Event()
def _AcquireExclusive():
......@@ -653,11 +649,8 @@ class TestSharedLock(_ThreadedTestCase):
# Notify main thread
exclev.set()
exclsync.acquire()
try:
exclsync.wait()
finally:
exclsync.release()
# Wait for notification from main thread
exclsync.wait()
self.sl.release()
......@@ -667,11 +660,7 @@ class TestSharedLock(_ThreadedTestCase):
self.failIf(self.sl.acquire(shared=0, timeout=0.02))
# Make all shared holders release their locks
sync.acquire()
try:
sync.notifyAll()
finally:
sync.release()
sync.set()
# Wait for exclusive acquire to succeed
exclev.wait()
......@@ -690,11 +679,7 @@ class TestSharedLock(_ThreadedTestCase):
self._addThread(target=_AcquireSharedSimple)
# Tell exclusive lock to release
exclsync.acquire()
try:
exclsync.notifyAll()
finally:
exclsync.release()
exclsync.set()
# Wait for everything to finish
self._waitThreads()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment