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

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