Try to repair at least one segfault on the Mac buildbot,

as diagnosed by Nick Coghlan.

test_capi.py:  A test module should never spawn a thread as
a side effect of being imported.  Because this one did, the
segfault one of its thread tests caused didn't occur until
a few tests after test_regrtest.py thought test_capi was
finished.  Repair that.  Also join() the thread spawned
at the end, so that test_capi is truly finished when
regrtest reports that it's done.

_testcapimodule.c test_thread_state():  this spawns a
couple of non-threading.py threads, passing them a PyObject*
argument, but did nothing to ensure that those threads
finished before returning.  As a result, the PyObject*
_could_ (although this was unlikely) get decref'ed out of
existence before the threads got around to using it.
Added explicit synchronization (via a Python mutex) so
that test_thread_state can reliably wait for its spawned
threads to finish.
This commit is contained in:
Tim Peters 2006-03-21 03:58:41 +00:00
parent 66760f87b5
commit 59b96c1029
2 changed files with 83 additions and 46 deletions

View file

@ -5,44 +5,51 @@ import sys
from test import test_support
import _testcapi
for name in dir(_testcapi):
if name.startswith('test_'):
test = getattr(_testcapi, name)
def test_main():
for name in dir(_testcapi):
if name.startswith('test_'):
test = getattr(_testcapi, name)
if test_support.verbose:
print "internal", name
try:
test()
except _testcapi.error:
raise test_support.TestFailed, sys.exc_info()[1]
# some extra thread-state tests driven via _testcapi
def TestThreadState():
import thread
import time
if test_support.verbose:
print "internal", name
try:
test()
except _testcapi.error:
raise test_support.TestFailed, sys.exc_info()[1]
print "auto-thread-state"
# some extra thread-state tests driven via _testcapi
def TestThreadState():
import thread
import time
idents = []
if test_support.verbose:
print "auto-thread-state"
def callback():
idents.append(thread.get_ident())
idents = []
_testcapi._test_thread_state(callback)
a = b = callback
time.sleep(1)
# Check our main thread is in the list exactly 3 times.
if idents.count(thread.get_ident()) != 3:
raise test_support.TestFailed, \
"Couldn't find main thread correctly in the list"
def callback():
idents.append(thread.get_ident())
try:
_testcapi._test_thread_state
have_thread_state = True
except AttributeError:
have_thread_state = False
_testcapi._test_thread_state(callback)
time.sleep(1)
# Check our main thread is in the list exactly 3 times.
if idents.count(thread.get_ident()) != 3:
raise test_support.TestFailed, \
"Couldn't find main thread correctly in the list"
if have_thread_state:
TestThreadState()
import threading
t=threading.Thread(target=TestThreadState)
t.start()
t.join()
try:
_testcapi._test_thread_state
have_thread_state = True
except AttributeError:
have_thread_state = False
if have_thread_state:
TestThreadState()
import threading
t=threading.Thread(target=TestThreadState)
t.start()
if __name__ == "__main__":
test_main()