summaryrefslogtreecommitdiffstats
path: root/Lib/threading.py
diff options
context:
space:
mode:
authorBrett Cannon <bcannon@gmail.com>2004-07-21 02:21:58 (GMT)
committerBrett Cannon <bcannon@gmail.com>2004-07-21 02:21:58 (GMT)
commit8b3d92a9777d7ea5805c5e3cf0d6b0474fab2d01 (patch)
treeb43d1ba3f7c88cb17bd52859ed7aaacd8d17a2ff /Lib/threading.py
parent7728b4719e08cb64d4c77051338c2b54a57b867e (diff)
downloadcpython-8b3d92a9777d7ea5805c5e3cf0d6b0474fab2d01.zip
cpython-8b3d92a9777d7ea5805c5e3cf0d6b0474fab2d01.tar.gz
cpython-8b3d92a9777d7ea5805c5e3cf0d6b0474fab2d01.tar.bz2
Fix bug where a KeyError was raised if -O was being used for the interpreter
and Thread.__delete() was called after a Thread instance was created. Problem resulted from a currentThread() call in an 'assert' statement being optimized out and dummy_thread.get_ident() always returning -1 and thus overwriting the entry for the _MainThread() instance created in 'threading' at import time. Closes bug #993394.
Diffstat (limited to 'Lib/threading.py')
-rw-r--r--Lib/threading.py34
1 files changed, 33 insertions, 1 deletions
diff --git a/Lib/threading.py b/Lib/threading.py
index c485524..2e6fab9 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -493,8 +493,40 @@ class Thread(_Verbose):
self.__block.release()
def __delete(self):
+ """Remove the current thread from the dict of currently running
+ threads.
+
+ Must take care to not raise an exception if dummy_thread is being used
+ (and thus this module is being used as an instance of dummy_threading).
+ Since dummy_thread.get_ident() always returns -1 since there is only one
+ thread if dummy_thread is being used. This means that if any Thread
+ instances are created they will overwrite any other threads registered.
+
+ This is an issue with this method, though, since an instance of
+ _MainThread is always created by 'threading'. This gets overwritten the
+ instant an instance of Thread is created; both threads will have -1 as
+ their value from dummy_thread.get_ident() and thus have the same key in
+ the dict. This means that when the _MainThread instance created by
+ 'threading' tries to clean itself up when atexit calls this method it
+ gets a key error if another Thread instance was created since that
+ removed the only thing with the key of -1.
+
+ This all means that KeyError from trying to delete something from
+ _active if dummy_threading is being used is a red herring. But since
+ it isn't if dummy_threading is *not* being used then don't hide the
+ exception. Also don't need to worry about issues from interpreter
+ shutdown and sys not being defined because the call is protected by a
+ blanket try/except block where that could be a problem.
+
+ """
_active_limbo_lock.acquire()
- del _active[_get_ident()]
+ if _sys.modules.has_key('dummy_threading'):
+ try:
+ del _active[_get_ident()]
+ except KeyError:
+ pass
+ else:
+ del _active[_get_ident()]
_active_limbo_lock.release()
def join(self, timeout=None):