bpo-10978: Semaphores can release multiple threads at a time (GH-15588)

This commit is contained in:
Raymond Hettinger 2019-08-29 01:45:19 -07:00 committed by GitHub
parent 0dac68f1e5
commit 35f6301d68
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 13 deletions

View file

@ -439,16 +439,19 @@ class Semaphore:
__enter__ = acquire
def release(self):
"""Release a semaphore, incrementing the internal counter by one.
def release(self, n=1):
"""Release a semaphore, incrementing the internal counter by one or more.
When the counter is zero on entry and another thread is waiting for it
to become larger than zero again, wake up that thread.
"""
if n < 1:
raise ValueError('n must be one or more')
with self._cond:
self._value += 1
self._cond.notify()
self._value += n
for i in range(n):
self._cond.notify()
def __exit__(self, t, v, tb):
self.release()
@ -475,8 +478,8 @@ class BoundedSemaphore(Semaphore):
Semaphore.__init__(self, value)
self._initial_value = value
def release(self):
"""Release a semaphore, incrementing the internal counter by one.
def release(self, n=1):
"""Release a semaphore, incrementing the internal counter by one or more.
When the counter is zero on entry and another thread is waiting for it
to become larger than zero again, wake up that thread.
@ -485,11 +488,14 @@ class BoundedSemaphore(Semaphore):
raise a ValueError.
"""
if n < 1:
raise ValueError('n must be one or more')
with self._cond:
if self._value >= self._initial_value:
if self._value + n > self._initial_value:
raise ValueError("Semaphore released too many times")
self._value += 1
self._cond.notify()
self._value += n
for i in range(n):
self._cond.notify()
class Event: