Issue 19158: a rare race in BoundedSemaphore could allow .release() too often.

This commit is contained in:
Tim Peters 2013-10-08 21:12:58 -05:00
commit e99bdb9694
2 changed files with 23 additions and 3 deletions

View File

@ -599,6 +599,24 @@ class ThreadTests(BaseTestCase):
time.sleep(0.01)
self.assertIn(LOOKING_FOR, repr(t)) # we waited at least 5 seconds
def test_BoundedSemaphore_limit(self):
# BoundedSemaphore should raise ValueError if released too often.
for limit in range(1, 10):
bs = threading.BoundedSemaphore(limit)
threads = [threading.Thread(target=bs.acquire)
for _ in range(limit)]
for t in threads:
t.start()
for t in threads:
t.join()
threads = [threading.Thread(target=bs.release)
for _ in range(limit)]
for t in threads:
t.start()
for t in threads:
t.join()
self.assertRaises(ValueError, bs.release)
class ThreadJoinOnShutdown(BaseTestCase):
def _run_and_join(self, script):

View File

@ -289,9 +289,11 @@ class BoundedSemaphore(Semaphore):
self._initial_value = value
def release(self):
if self._value >= self._initial_value:
raise ValueError("Semaphore released too many times")
return Semaphore.release(self)
with self._cond:
if self._value >= self._initial_value:
raise ValueError("Semaphore released too many times")
self._value += 1
self._cond.notify()
class Event: