[Python-checkins] r61984 - in python/trunk/Lib: test/test_threading.py threading.py

jeffrey.yasskin python-checkins at python.org
Fri Mar 28 05:11:18 CET 2008


Author: jeffrey.yasskin
Date: Fri Mar 28 05:11:18 2008
New Revision: 61984
Modified:
 python/trunk/Lib/test/test_threading.py
 python/trunk/Lib/threading.py
Log:
Kill a race in test_threading in which the exception info in a thread finishing
up after it was joined had a traceback pointing to that thread's (deleted)
target attribute, while the test was trying to check that the target was
destroyed. Big thanks to Antoine Pitrou for diagnosing the race and pointing
out sys.exc_clear() to kill the exception early. This fixes issue 2496.
Modified: python/trunk/Lib/test/test_threading.py
==============================================================================
--- python/trunk/Lib/test/test_threading.py	(original)
+++ python/trunk/Lib/test/test_threading.py	Fri Mar 28 05:11:18 2008
@@ -276,13 +276,17 @@
 weak_cyclic_object = weakref.ref(cyclic_object)
 cyclic_object.thread.join()
 del cyclic_object
- self.assertEquals(None, weak_cyclic_object())
+ self.assertEquals(None, weak_cyclic_object(),
+ msg=('%d references still around' %
+ sys.getrefcount(weak_cyclic_object())))
 
 raising_cyclic_object = RunSelfFunction(should_raise=True)
 weak_raising_cyclic_object = weakref.ref(raising_cyclic_object)
 raising_cyclic_object.thread.join()
 del raising_cyclic_object
- self.assertEquals(None, weak_raising_cyclic_object())
+ self.assertEquals(None, weak_raising_cyclic_object(),
+ msg=('%d references still around' %
+ sys.getrefcount(weak_raising_cyclic_object())))
 
 
 class ThreadingExceptionTests(unittest.TestCase):
Modified: python/trunk/Lib/threading.py
==============================================================================
--- python/trunk/Lib/threading.py	(original)
+++ python/trunk/Lib/threading.py	Fri Mar 28 05:11:18 2008
@@ -392,6 +392,9 @@
 # shutdown and thus raises an exception about trying to perform some
 # operation on/with a NoneType
 __exc_info = _sys.exc_info
+ # Keep sys.exc_clear too to clear the exception just before
+ # allowing .join() to return.
+ __exc_clear = _sys.exc_clear
 
 def __init__(self, group=None, target=None, name=None,
 args=(), kwargs=None, verbose=None):
@@ -527,6 +530,12 @@
 else:
 if __debug__:
 self._note("%s.__bootstrap(): normal return", self)
+ finally:
+ # Prevent a race in
+ # test_threading.test_no_refcycle_through_target when
+ # the exception keeps the target alive past when we
+ # assert that it's dead.
+ self.__exc_clear()
 finally:
 with _active_limbo_lock:
 self.__stop()


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /