diff -r b0f9dce98e5c Lib/threading.py --- a/Lib/threading.py Tue Oct 27 21:14:04 2009 +0100 +++ b/Lib/threading.py Wed Oct 28 00:53:09 2009 +0100 @@ -1,6 +1,7 @@ """Thread module emulating a subset of Java's threading model.""" import sys as _sys +import weakref try: import thread @@ -436,7 +437,8 @@ class Thread(_Verbose): self.__ident = None self.__started = Event() self.__stopped = False - self.__block = Condition(Lock()) + self.__wr = None + self.__finished = Event() self.__initialized = True # sys.stderr is not stored in the class like # sys.exc_info since it can be changed between instances @@ -468,7 +470,11 @@ class Thread(_Verbose): self._note("%s.start(): starting thread", self) with _active_limbo_lock: _limbo[self] = self - _start_new_thread(self.__bootstrap, ()) + def task(func=self.__bootstrap): + func() + _start_new_thread(task, ()) + self.__wr = weakref.ref(task, lambda _, evt=self.__finished: evt.set()) + del task self.__started.wait() def run(self): @@ -578,10 +584,7 @@ class Thread(_Verbose): pass def __stop(self): - self.__block.acquire() self.__stopped = True - self.__block.notify_all() - self.__block.release() def __delete(self): "Remove current thread from the dict of currently running threads." @@ -629,27 +632,13 @@ class Thread(_Verbose): if __debug__: if not self.__stopped: self._note("%s.join(): waiting until thread stops", self) - self.__block.acquire() - try: - if timeout is None: - while not self.__stopped: - self.__block.wait() - if __debug__: - self._note("%s.join(): thread stopped", self) + + joined = self.__finished.wait(timeout) + if __debug__: + if joined: + self._note("%s.join(): thread stopped", self) else: - deadline = _time() + timeout - while not self.__stopped: - delay = deadline - _time() - if delay <= 0: - if __debug__: - self._note("%s.join(): timed out", self) - break - self.__block.wait(delay) - else: - if __debug__: - self._note("%s.join(): thread stopped", self) - finally: - self.__block.release() + self._note("%s.join(): timed out", self) @property def name(self): @@ -745,6 +734,7 @@ class _MainThread(Thread): def _exitfunc(self): self._Thread__stop() + self._Thread__finished.set() t = _pickSomeNonDaemonThread() if t: if __debug__: @@ -776,11 +766,6 @@ class _DummyThread(Thread): def __init__(self): Thread.__init__(self, name=_newname("Dummy-%d")) - # Thread.__block consumes an OS-level locking primitive, which - # can never be used by a _DummyThread. Since a _DummyThread - # instance is immortal, that's bad, so release this resource. - del self._Thread__block - self._Thread__started.set() self._set_ident() with _active_limbo_lock: @@ -854,10 +839,8 @@ def _after_fork(): new_active[ident] = thread else: # All the others are already stopped. - # We don't call _Thread__stop() because it tries to acquire - # thread._Thread__block which could also have been held while - # we forked. thread._Thread__stopped = True + thread._Thread__finished.set() _limbo.clear() _active.clear()