mirror of
https://github.com/python/cpython.git
synced 2025-10-10 00:43:41 +00:00
Issue #7316: the acquire() method of lock objects in the :mod:threading
module now takes an optional timeout argument in seconds. Timeout support relies on the system threading library, so as to avoid a semi-busy wait loop.
This commit is contained in:
parent
e53de3dc4a
commit
7c3e577395
11 changed files with 326 additions and 77 deletions
|
@ -31,6 +31,7 @@ try:
|
|||
_CRLock = _thread.RLock
|
||||
except AttributeError:
|
||||
_CRLock = None
|
||||
TIMEOUT_MAX = _thread.TIMEOUT_MAX
|
||||
del _thread
|
||||
|
||||
|
||||
|
@ -107,14 +108,14 @@ class _RLock(_Verbose):
|
|||
return "<%s owner=%r count=%d>" % (
|
||||
self.__class__.__name__, owner, self._count)
|
||||
|
||||
def acquire(self, blocking=True):
|
||||
def acquire(self, blocking=True, timeout=-1):
|
||||
me = _get_ident()
|
||||
if self._owner == me:
|
||||
self._count = self._count + 1
|
||||
if __debug__:
|
||||
self._note("%s.acquire(%s): recursive success", self, blocking)
|
||||
return 1
|
||||
rc = self._block.acquire(blocking)
|
||||
rc = self._block.acquire(blocking, timeout)
|
||||
if rc:
|
||||
self._owner = me
|
||||
self._count = 1
|
||||
|
@ -234,22 +235,10 @@ class _Condition(_Verbose):
|
|||
if __debug__:
|
||||
self._note("%s.wait(): got it", self)
|
||||
else:
|
||||
# Balancing act: We can't afford a pure busy loop, so we
|
||||
# have to sleep; but if we sleep the whole timeout time,
|
||||
# we'll be unresponsive. The scheme here sleeps very
|
||||
# little at first, longer as time goes on, but never longer
|
||||
# than 20 times per second (or the timeout time remaining).
|
||||
endtime = _time() + timeout
|
||||
delay = 0.0005 # 500 us -> initial delay of 1 ms
|
||||
while True:
|
||||
gotit = waiter.acquire(0)
|
||||
if gotit:
|
||||
break
|
||||
remaining = endtime - _time()
|
||||
if remaining <= 0:
|
||||
break
|
||||
delay = min(delay * 2, remaining, .05)
|
||||
_sleep(delay)
|
||||
if timeout > 0:
|
||||
gotit = waiter.acquire(True, timeout)
|
||||
else:
|
||||
gotit = waiter.acquire(False)
|
||||
if not gotit:
|
||||
if __debug__:
|
||||
self._note("%s.wait(%s): timed out", self, timeout)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue