diff options
author | Brett Cannon <bcannon@gmail.com> | 2004-07-21 02:21:58 (GMT) |
---|---|---|
committer | Brett Cannon <bcannon@gmail.com> | 2004-07-21 02:21:58 (GMT) |
commit | 8b3d92a9777d7ea5805c5e3cf0d6b0474fab2d01 (patch) | |
tree | b43d1ba3f7c88cb17bd52859ed7aaacd8d17a2ff /Lib | |
parent | 7728b4719e08cb64d4c77051338c2b54a57b867e (diff) | |
download | cpython-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')
-rw-r--r-- | Lib/threading.py | 34 |
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): |