]> granicus.if.org Git - python/commitdiff
Fix bug where a KeyError was raised if -O was being used for the interpreter
authorBrett Cannon <bcannon@gmail.com>
Wed, 21 Jul 2004 02:21:58 +0000 (02:21 +0000)
committerBrett Cannon <bcannon@gmail.com>
Wed, 21 Jul 2004 02:21:58 +0000 (02:21 +0000)
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.

Lib/threading.py
Misc/NEWS

index c48552458f6f3eaa77399d03c4e113efa9ea025d..2e6fab9f9b7cc788d861cf660866a74ee0469a4c 100644 (file)
@@ -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):
index f6792396fd73806185822d8651f1fccc2a5ddce3..af7b384b59d5b381b5e266d7235ae5e96da6d6dc 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -39,6 +39,10 @@ Extension modules
 Library
 -------
 
+- Bug #993394.  Fix a possible red herring of KeyError in 'threading' being
+  raised during interpreter shutdown from a registered function with atexit
+  when dummy_threading is being used.
+
 - Bug #857297/Patch #916874.  Fix an error when extracting a hard link
   from a tarfile.