Blame SOURCES/00257-threading-condition-wait.patch

956e31
diff --git a/Lib/threading.py b/Lib/threading.py
956e31
index 7ab9ad8..dcedd3b 100644
956e31
--- a/Lib/threading.py
956e31
+++ b/Lib/threading.py
956e31
@@ -3,7 +3,7 @@
956e31
 import sys as _sys
956e31
 import _thread
956e31
 
956e31
-from time import monotonic as _time
956e31
+from time import monotonic as _time, sleep as _sleep
956e31
 from traceback import format_exc as _format_exc
956e31
 from _weakrefset import WeakSet
956e31
 from itertools import islice as _islice, count as _count
956e31
@@ -296,7 +296,25 @@ class Condition:
956e31
                 gotit = True
956e31
             else:
956e31
                 if timeout > 0:
956e31
-                    gotit = waiter.acquire(True, timeout)
956e31
+                    # rhbz#2003758: Avoid waiter.acquire(True, timeout) since
956e31
+                    # it uses the system clock internally.
956e31
+                    #
956e31
+                    # Balancing act:  We can't afford a pure busy loop, so we
956e31
+                    # have to sleep; but if we sleep the whole timeout time,
956e31
+                    # we'll be unresponsive.  The scheme here sleeps very
956e31
+                    # little at first, longer as time goes on, but never longer
956e31
+                    # than 20 times per second (or the timeout time remaining).
956e31
+                    endtime = _time() + timeout
956e31
+                    delay = 0.0005 # 500 us -> initial delay of 1 ms
956e31
+                    while True:
956e31
+                        gotit = waiter.acquire(0)
956e31
+                        if gotit:
956e31
+                            break
956e31
+                        remaining = min(endtime - _time(), timeout)
956e31
+                        if remaining <= 0:
956e31
+                            break
956e31
+                        delay = min(delay * 2, remaining, .05)
956e31
+                        _sleep(delay)
956e31
                 else:
956e31
                     gotit = waiter.acquire(False)
956e31
             return gotit