Commit aff1688e authored by Tim Peters's avatar Tim Peters

Thread.__delete: Discussion of internal obscurities belongs in comments

rather than in docstrings.  Rewrote so that _active_limbo_lock is released
no matter what happens (it could have been left locked if _sys got None'd
out).  Use "in" in preference to has_key() for dict lookup.  Don't bother
looking for 'dummy_threading' in sys.modules unless KeyError is raised.
Since the heart of the method is the del, do that in only one place.
parent e010388c
...@@ -493,41 +493,38 @@ class Thread(_Verbose): ...@@ -493,41 +493,38 @@ class Thread(_Verbose):
self.__block.release() self.__block.release()
def __delete(self): def __delete(self):
"""Remove the current thread from the dict of currently running "Remove current thread from the dict of currently running threads."
threads.
# Notes about running with dummy_thread:
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). # Must take care to not raise an exception if dummy_thread is being
Since dummy_thread.get_ident() always returns -1 since there is only one # used (and thus this module is being used as an instance of
thread if dummy_thread is being used. This means that if any Thread # dummy_threading). dummy_thread.get_ident() always returns -1 since
instances are created they will overwrite any other threads registered. # there is only one thread if dummy_thread is being used. Thus
# len(_active) is always <= 1 here, and any Thread instance created
This is an issue with this method, though, since an instance of # overwrites the (if any) thread currently registered in _active.
_MainThread is always created by 'threading'. This gets overwritten the #
instant an instance of Thread is created; both threads will have -1 as # An instance of _MainThread is always created by 'threading'. This
their value from dummy_thread.get_ident() and thus have the same key in # gets overwritten the instant an instance of Thread is created; both
the dict. This means that when the _MainThread instance created by # threads return -1 from dummy_thread.get_ident() and thus have the
'threading' tries to clean itself up when atexit calls this method it # same key in the dict. So when the _MainThread instance created by
gets a key error if another Thread instance was created since that # 'threading' tries to clean itself up when atexit calls this method
removed the only thing with the key of -1. # it gets a KeyError if another Thread instance was created.
#
This all means that KeyError from trying to delete something from # This all means that KeyError from trying to delete something from
_active if dummy_threading is being used is a red herring. But since # _active if dummy_threading is being used is a red herring. But
it isn't if dummy_threading is *not* being used then don't hide the # since it isn't if dummy_threading is *not* being used then don't
exception. Also don't need to worry about issues from interpreter # hide the exception.
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() _active_limbo_lock.acquire()
if _sys.modules.has_key('dummy_threading'): try:
try: try:
del _active[_get_ident()] del _active[_get_ident()]
except KeyError: except KeyError:
pass if 'dummy_threading' not in _sys.modules:
else: raise
del _active[_get_ident()] finally:
_active_limbo_lock.release() _active_limbo_lock.release()
def join(self, timeout=None): def join(self, timeout=None):
assert self.__initialized, "Thread.__init__() not called" assert self.__initialized, "Thread.__init__() not called"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment