[Python-checkins] r85876 - in python/branches/py3k: Doc/library/threading.rst Lib/test/lock_tests.py Lib/threading.py Misc/NEWS

georg.brandl python-checkins at python.org
Thu Oct 28 11:03:20 CEST 2010


Author: georg.brandl
Date: Thu Oct 28 11:03:20 2010
New Revision: 85876

Log:
#10218: return timeout status from Condition.wait, mirroring other primitives' behavior.

Modified:
   python/branches/py3k/Doc/library/threading.rst
   python/branches/py3k/Lib/test/lock_tests.py
   python/branches/py3k/Lib/threading.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Doc/library/threading.rst
==============================================================================
--- python/branches/py3k/Doc/library/threading.rst	(original)
+++ python/branches/py3k/Doc/library/threading.rst	Thu Oct 28 11:03:20 2010
@@ -574,6 +574,12 @@
       interface is then used to restore the recursion level when the lock is
       reacquired.
 
+      The return value is ``True`` unless a given *timeout* expired, in which
+      case it is ``False``.
+
+      .. versionchanged:: 3.2
+         Previously, the method always returned ``None``.
+
    .. method:: notify()
 
       Wake up a thread waiting on this condition, if any.  If the calling thread

Modified: python/branches/py3k/Lib/test/lock_tests.py
==============================================================================
--- python/branches/py3k/Lib/test/lock_tests.py	(original)
+++ python/branches/py3k/Lib/test/lock_tests.py	Thu Oct 28 11:03:20 2010
@@ -375,13 +375,13 @@
         phase_num = 0
         def f():
             cond.acquire()
-            cond.wait()
+            result = cond.wait()
             cond.release()
-            results1.append(phase_num)
+            results1.append((result, phase_num))
             cond.acquire()
-            cond.wait()
+            result = cond.wait()
             cond.release()
-            results2.append(phase_num)
+            results2.append((result, phase_num))
         b = Bunch(f, N)
         b.wait_for_started()
         _wait()
@@ -394,7 +394,7 @@
         cond.release()
         while len(results1) < 3:
             _wait()
-        self.assertEqual(results1, [1] * 3)
+        self.assertEqual(results1, [(True, 1)] * 3)
         self.assertEqual(results2, [])
         # Notify 5 threads: they might be in their first or second wait
         cond.acquire()
@@ -404,8 +404,8 @@
         cond.release()
         while len(results1) + len(results2) < 8:
             _wait()
-        self.assertEqual(results1, [1] * 3 + [2] * 2)
-        self.assertEqual(results2, [2] * 3)
+        self.assertEqual(results1, [(True, 1)] * 3 + [(True, 2)] * 2)
+        self.assertEqual(results2, [(True, 2)] * 3)
         # Notify all threads: they are all in their second wait
         cond.acquire()
         cond.notify_all()
@@ -414,8 +414,8 @@
         cond.release()
         while len(results2) < 5:
             _wait()
-        self.assertEqual(results1, [1] * 3 + [2] * 2)
-        self.assertEqual(results2, [2] * 3 + [3] * 2)
+        self.assertEqual(results1, [(True, 1)] * 3 + [(True,2)] * 2)
+        self.assertEqual(results2, [(True, 2)] * 3 + [(True, 3)] * 2)
         b.wait_for_finished()
 
     def test_notify(self):
@@ -431,14 +431,20 @@
         def f():
             cond.acquire()
             t1 = time.time()
-            cond.wait(0.5)
+            result = cond.wait(0.5)
             t2 = time.time()
             cond.release()
-            results.append(t2 - t1)
+            results.append((t2 - t1, result))
         Bunch(f, N).wait_for_finished()
-        self.assertEqual(len(results), 5)
-        for dt in results:
+        self.assertEqual(len(results), N)
+        for dt, result in results:
             self.assertTimeout(dt, 0.5)
+            # Note that conceptually (that"s the condition variable protocol)
+            # a wait() may succeed even if no one notifies us and before any
+            # timeout occurs.  Spurious wakeups can occur.
+            # This makes it hard to verify the result value.
+            # In practice, this implementation has no spurious wakeups.
+            self.assertFalse(result)
 
 
 class BaseSemaphoreTests(BaseTestCase):

Modified: python/branches/py3k/Lib/threading.py
==============================================================================
--- python/branches/py3k/Lib/threading.py	(original)
+++ python/branches/py3k/Lib/threading.py	Thu Oct 28 11:03:20 2010
@@ -232,6 +232,7 @@
         try:    # restore state no matter what (e.g., KeyboardInterrupt)
             if timeout is None:
                 waiter.acquire()
+                gotit = True
                 if __debug__:
                     self._note("%s.wait(): got it", self)
             else:
@@ -249,6 +250,7 @@
                 else:
                     if __debug__:
                         self._note("%s.wait(%s): got it", self, timeout)
+            return gotit
         finally:
             self._acquire_restore(saved_state)
 

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Thu Oct 28 11:03:20 2010
@@ -51,6 +51,8 @@
 Library
 -------
 
+- Issue #10218: Return timeout status from ``Condition.wait`` in threading.
+
 - Issue #7351: Add ``zipfile.BadZipFile`` spelling of the exception name
   and deprecate the old name ``zipfile.BadZipfile``.
 


More information about the Python-checkins mailing list