mirror of
https://github.com/python/cpython.git
synced 2025-08-21 01:15:03 +00:00
Backport of r60190:
- Fix Issue #1703448: A joined thread could show up in the threading.enumerate() list after the join() for a brief period until it actually exited.
This commit is contained in:
parent
9f26fcce04
commit
8f034d9af2
3 changed files with 33 additions and 4 deletions
|
@ -3,6 +3,7 @@
|
||||||
import test.test_support
|
import test.test_support
|
||||||
from test.test_support import verbose
|
from test.test_support import verbose
|
||||||
import random
|
import random
|
||||||
|
import sys
|
||||||
import threading
|
import threading
|
||||||
import thread
|
import thread
|
||||||
import time
|
import time
|
||||||
|
@ -201,6 +202,24 @@ class ThreadTests(unittest.TestCase):
|
||||||
t.join()
|
t.join()
|
||||||
# else the thread is still running, and we have no way to kill it
|
# else the thread is still running, and we have no way to kill it
|
||||||
|
|
||||||
|
def test_enumerate_after_join(self):
|
||||||
|
# Try hard to trigger #1703448: a thread is still returned in
|
||||||
|
# threading.enumerate() after it has been join()ed.
|
||||||
|
enum = threading.enumerate
|
||||||
|
old_interval = sys.getcheckinterval()
|
||||||
|
sys.setcheckinterval(1)
|
||||||
|
try:
|
||||||
|
for i in xrange(1, 1000):
|
||||||
|
t = threading.Thread(target=lambda: None)
|
||||||
|
t.start()
|
||||||
|
t.join()
|
||||||
|
l = enum()
|
||||||
|
self.assertFalse(t in l,
|
||||||
|
"#1703448 triggered after %d trials: %s" % (i, l))
|
||||||
|
finally:
|
||||||
|
sys.setcheckinterval(old_interval)
|
||||||
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
test.test_support.run_unittest(ThreadTests)
|
test.test_support.run_unittest(ThreadTests)
|
||||||
|
|
||||||
|
|
|
@ -524,11 +524,17 @@ class Thread(_Verbose):
|
||||||
if __debug__:
|
if __debug__:
|
||||||
self._note("%s.__bootstrap(): normal return", self)
|
self._note("%s.__bootstrap(): normal return", self)
|
||||||
finally:
|
finally:
|
||||||
|
_active_limbo_lock.acquire()
|
||||||
|
try:
|
||||||
self.__stop()
|
self.__stop()
|
||||||
try:
|
try:
|
||||||
self.__delete()
|
# We don't call self.__delete() because it also
|
||||||
|
# grabs _active_limbo_lock.
|
||||||
|
del _active[_get_ident()]
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
finally:
|
||||||
|
_active_limbo_lock.release()
|
||||||
|
|
||||||
def __stop(self):
|
def __stop(self):
|
||||||
self.__block.acquire()
|
self.__block.acquire()
|
||||||
|
|
|
@ -55,6 +55,10 @@ Core and builtins
|
||||||
|
|
||||||
- Bug #1733488: Fix compilation of bufferobject.c on AIX.
|
- Bug #1733488: Fix compilation of bufferobject.c on AIX.
|
||||||
|
|
||||||
|
- Fix Issue #1703448: A joined thread could show up in the
|
||||||
|
threading.enumerate() list after the join() for a brief period until
|
||||||
|
it actually exited.
|
||||||
|
|
||||||
|
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue