summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2001-08-12 00:41:33 (GMT)
committerTim Peters <tim.peters@gmail.com>2001-08-12 00:41:33 (GMT)
commita6a4f27ef7c80e6dee626d6649f2019544b24f65 (patch)
tree7cef1d9b288c2db5df04bbeaf2fff5af8b033ae0 /Lib
parentce3016a142bffd930f29756bb783c8e5769254e7 (diff)
downloadcpython-a6a4f27ef7c80e6dee626d6649f2019544b24f65.zip
cpython-a6a4f27ef7c80e6dee626d6649f2019544b24f65.tar.gz
cpython-a6a4f27ef7c80e6dee626d6649f2019544b24f65.tar.bz2
_Condition.wait(): never sleep longer than the timeout time remaining,
and even if we have a long time left to wait, try the lock at least 20 times/second.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/threading.py15
1 files changed, 11 insertions, 4 deletions
diff --git a/Lib/threading.py b/Lib/threading.py
index c5e65d9..74e93bb 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -191,15 +191,22 @@ 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.000001 # 1 usec
+ delay = 0.0005 # 500 us -> initial delay of 1 ms
while 1:
gotit = waiter.acquire(0)
- if gotit or _time() >= endtime:
+ if gotit:
break
+ remaining = endtime - _time()
+ if remaining <= 0:
+ break
+ delay = min(delay * 2, remaining, .05)
_sleep(delay)
- if delay < 1.0:
- delay = delay * 2.0
if not gotit:
if __debug__:
self._note("%s.wait(%s): timed out", self, timeout)