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

This commit is contained in:
Tim Peters 2013-10-08 20:55:51 -05:00
parent ee82d0b293
commit 7634e1cf90
2 changed files with 23 additions and 3 deletions

View file

@ -468,6 +468,24 @@ def test_is_alive_after_fork(self):
self.assertEqual(0, status)
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):
# Between fork() and exec(), only async-safe functions are allowed (issues

View file

@ -283,9 +283,11 @@ def __init__(self, value=1):
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: