threading._DummyThread.__init__(): document obscure new code.
test_threading.test_foreign_thread(): new test does a basic check that "foreign" threads can using the threading module, and that they create a _DummyThread instance in at least one use case. This isn't a very good test, since a thread created by thread.start_new_thread() isn't particularly "foreign".
This commit is contained in:
parent
84d548994e
commit
711906e0c2
|
@ -4,6 +4,7 @@ import test.test_support
|
|||
from test.test_support import verbose
|
||||
import random
|
||||
import threading
|
||||
import thread
|
||||
import time
|
||||
import unittest
|
||||
|
||||
|
@ -78,11 +79,31 @@ class ThreadTests(unittest.TestCase):
|
|||
if verbose:
|
||||
print 'waiting for all tasks to complete'
|
||||
for t in threads:
|
||||
t.join()
|
||||
t.join(NUMTASKS)
|
||||
self.assert_(not t.isAlive())
|
||||
if verbose:
|
||||
print 'all tasks done'
|
||||
self.assertEqual(numrunning.get(), 0)
|
||||
|
||||
def test_foreign_thread(self):
|
||||
# Check that a "foreign" thread can use the threading module.
|
||||
def f(mutex):
|
||||
# Acquiring an RLock forces an entry for the foreign
|
||||
# thread to get made in the threading._active map.
|
||||
r = threading.RLock()
|
||||
r.acquire()
|
||||
r.release()
|
||||
mutex.release()
|
||||
|
||||
mutex = threading.Lock()
|
||||
mutex.acquire()
|
||||
tid = thread.start_new_thread(f, (mutex,))
|
||||
# Wait for the thread to finish.
|
||||
mutex.acquire()
|
||||
self.assert_(tid in threading._active)
|
||||
self.assert_(isinstance(threading._active[tid],
|
||||
threading._DummyThread))
|
||||
del threading._active[tid]
|
||||
|
||||
def test_main():
|
||||
test.test_support.run_unittest(ThreadTests)
|
||||
|
|
|
@ -358,7 +358,7 @@ def _newname(template="Thread-%d"):
|
|||
|
||||
# Active thread administration
|
||||
_active_limbo_lock = _allocate_lock()
|
||||
_active = {}
|
||||
_active = {} # maps thread id to Thread object
|
||||
_limbo = {}
|
||||
|
||||
|
||||
|
@ -643,8 +643,9 @@ def _pickSomeNonDaemonThread():
|
|||
|
||||
|
||||
# Dummy thread class to represent threads not started here.
|
||||
# These aren't garbage collected when they die,
|
||||
# nor can they be waited for.
|
||||
# These aren't garbage collected when they die, nor can they be waited for.
|
||||
# If they invoke anything in threading.py that calls currentThread(), they
|
||||
# leave an entry in the _active dict forever after.
|
||||
# Their purpose is to return *something* from currentThread().
|
||||
# They are marked as daemon threads so we won't wait for them
|
||||
# when we exit (conform previous semantics).
|
||||
|
@ -653,7 +654,12 @@ 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 = True
|
||||
_active_limbo_lock.acquire()
|
||||
_active[_get_ident()] = self
|
||||
|
|
Loading…
Reference in New Issue