diff options
author | Benjamin Peterson <benjamin@python.org> | 2008-06-13 00:26:50 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2008-06-13 00:26:50 (GMT) |
commit | e68df0fbe51fc6980d48265e85664341f74fc9eb (patch) | |
tree | 4a6e06a0b0bd84c015718525809e581c828c5bec | |
parent | 762681b5152671802d315833a661a79d01f2c5e7 (diff) | |
download | cpython-e68df0fbe51fc6980d48265e85664341f74fc9eb.zip cpython-e68df0fbe51fc6980d48265e85664341f74fc9eb.tar.gz cpython-e68df0fbe51fc6980d48265e85664341f74fc9eb.tar.bz2 |
Merged revisions 64212 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r64212 | benjamin.peterson | 2008-06-12 19:09:47 -0500 (Thu, 12 Jun 2008) | 3 lines
#1683 prevent forking from interfering in threading storage
This should prevent some test_multiprocessing failures
........
-rw-r--r-- | Include/pythread.h | 3 | ||||
-rw-r--r-- | Modules/signalmodule.c | 1 | ||||
-rw-r--r-- | Parser/intrcheck.c | 2 | ||||
-rw-r--r-- | Python/thread.c | 31 |
4 files changed, 37 insertions, 0 deletions
diff --git a/Include/pythread.h b/Include/pythread.h index f26db16..b5a6ec3 100644 --- a/Include/pythread.h +++ b/Include/pythread.h @@ -40,6 +40,9 @@ PyAPI_FUNC(int) PyThread_set_key_value(int, void *); PyAPI_FUNC(void *) PyThread_get_key_value(int); PyAPI_FUNC(void) PyThread_delete_key_value(int key); +/* Cleanup after a fork */ +PyAPI_FUNC(void) PyThread_ReInitTLS(void); + #ifdef __cplusplus } #endif diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 15cd964..e190429 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -941,5 +941,6 @@ PyOS_AfterFork(void) main_thread = PyThread_get_thread_ident(); main_pid = getpid(); _PyImport_ReInitLock(); + PyThread_ReInitTLS(); #endif } diff --git a/Parser/intrcheck.c b/Parser/intrcheck.c index 5285dc5..06b5840 100644 --- a/Parser/intrcheck.c +++ b/Parser/intrcheck.c @@ -2,6 +2,7 @@ /* Check for interrupts */ #include "Python.h" +#include "pythread.h" #ifdef QUICKWIN @@ -168,5 +169,6 @@ PyOS_AfterFork(void) { #ifdef WITH_THREAD PyEval_ReInitThreads(); + PyThread_ReInitTLS(); #endif } diff --git a/Python/thread.c b/Python/thread.c index f2da8c6..41fa1e6 100644 --- a/Python/thread.c +++ b/Python/thread.c @@ -377,4 +377,35 @@ PyThread_delete_key_value(int key) PyThread_release_lock(keymutex); } +/* Forget everything not associated with the current thread id. + * This function is called from PyOS_AfterFork(). It is necessary + * because other thread ids which were in use at the time of the fork + * may be reused for new threads created in the forked process. + */ +void +PyThread_ReInitTLS(void) +{ + long id = PyThread_get_thread_ident(); + struct key *p, **q; + + if (!keymutex) + return; + + /* As with interpreter_lock in PyEval_ReInitThreads() + we just create a new lock without freeing the old one */ + keymutex = PyThread_allocate_lock(); + + /* Delete all keys which do not match the current thread id */ + q = &keyhead; + while ((p = *q) != NULL) { + if (p->id != id) { + *q = p->next; + free((void *)p); + /* NB This does *not* free p->value! */ + } + else + q = &p->next; + } +} + #endif /* Py_HAVE_NATIVE_TLS */ |