diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2010-04-14 15:44:10 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2010-04-14 15:44:10 (GMT) |
commit | 7c3e5773954009d65520eb063621cf7724da88e3 (patch) | |
tree | 12c9dc646c8a80043616bf4fa54e3dedb84df9ca /Lib/threading.py | |
parent | e53de3dc4a9021b5edabd44fd495df7770b6249c (diff) | |
download | cpython-7c3e5773954009d65520eb063621cf7724da88e3.zip cpython-7c3e5773954009d65520eb063621cf7724da88e3.tar.gz cpython-7c3e5773954009d65520eb063621cf7724da88e3.tar.bz2 |
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.
Diffstat (limited to 'Lib/threading.py')
-rw-r--r-- | Lib/threading.py | 25 |
1 files changed, 7 insertions, 18 deletions
diff --git a/Lib/threading.py b/Lib/threading.py index 9f1525d..b4d07fe 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -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) |