Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e99bdb9

Browse files
author
Tim Peters
committed
Issue 19158: a rare race in BoundedSemaphore could allow .release() too often.
2 parents 77e904e + 7634e1c commit e99bdb9

2 files changed

Lines changed: 23 additions & 3 deletions

File tree

Lib/test/test_threading.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,24 @@ def f():
599599
time.sleep(0.01)
600600
self.assertIn(LOOKING_FOR, repr(t)) # we waited at least 5 seconds
601601

602+
def test_BoundedSemaphore_limit(self):
603+
# BoundedSemaphore should raise ValueError if released too often.
604+
for limit in range(1, 10):
605+
bs = threading.BoundedSemaphore(limit)
606+
threads = [threading.Thread(target=bs.acquire)
607+
for _ in range(limit)]
608+
for t in threads:
609+
t.start()
610+
for t in threads:
611+
t.join()
612+
threads = [threading.Thread(target=bs.release)
613+
for _ in range(limit)]
614+
for t in threads:
615+
t.start()
616+
for t in threads:
617+
t.join()
618+
self.assertRaises(ValueError, bs.release)
619+
602620
class ThreadJoinOnShutdown(BaseTestCase):
603621

604622
def _run_and_join(self, script):

Lib/threading.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,9 +289,11 @@ def __init__(self, value=1):
289289
self._initial_value = value
290290

291291
def release(self):
292-
if self._value >= self._initial_value:
293-
raise ValueError("Semaphore released too many times")
294-
return Semaphore.release(self)
292+
with self._cond:
293+
if self._value >= self._initial_value:
294+
raise ValueError("Semaphore released too many times")
295+
self._value += 1
296+
self._cond.notify()
295297

296298

297299
class Event:

0 commit comments

Comments
 (0)