Skip to content

Commit e68df0f

Browse files
committed
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 python#1683 prevent forking from interfering in threading storage This should prevent some test_multiprocessing failures ........
1 parent 762681b commit e68df0f

File tree

4 files changed

+37
-0
lines changed

4 files changed

+37
-0
lines changed

Include/pythread.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ PyAPI_FUNC(int) PyThread_set_key_value(int, void *);
4040
PyAPI_FUNC(void *) PyThread_get_key_value(int);
4141
PyAPI_FUNC(void) PyThread_delete_key_value(int key);
4242

43+
/* Cleanup after a fork */
44+
PyAPI_FUNC(void) PyThread_ReInitTLS(void);
45+
4346
#ifdef __cplusplus
4447
}
4548
#endif

Modules/signalmodule.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,5 +941,6 @@ PyOS_AfterFork(void)
941941
main_thread = PyThread_get_thread_ident();
942942
main_pid = getpid();
943943
_PyImport_ReInitLock();
944+
PyThread_ReInitTLS();
944945
#endif
945946
}

Parser/intrcheck.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/* Check for interrupts */
33

44
#include "Python.h"
5+
#include "pythread.h"
56

67
#ifdef QUICKWIN
78

@@ -168,5 +169,6 @@ PyOS_AfterFork(void)
168169
{
169170
#ifdef WITH_THREAD
170171
PyEval_ReInitThreads();
172+
PyThread_ReInitTLS();
171173
#endif
172174
}

Python/thread.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,4 +377,35 @@ PyThread_delete_key_value(int key)
377377
PyThread_release_lock(keymutex);
378378
}
379379

380+
/* Forget everything not associated with the current thread id.
381+
* This function is called from PyOS_AfterFork(). It is necessary
382+
* because other thread ids which were in use at the time of the fork
383+
* may be reused for new threads created in the forked process.
384+
*/
385+
void
386+
PyThread_ReInitTLS(void)
387+
{
388+
long id = PyThread_get_thread_ident();
389+
struct key *p, **q;
390+
391+
if (!keymutex)
392+
return;
393+
394+
/* As with interpreter_lock in PyEval_ReInitThreads()
395+
we just create a new lock without freeing the old one */
396+
keymutex = PyThread_allocate_lock();
397+
398+
/* Delete all keys which do not match the current thread id */
399+
q = &keyhead;
400+
while ((p = *q) != NULL) {
401+
if (p->id != id) {
402+
*q = p->next;
403+
free((void *)p);
404+
/* NB This does *not* free p->value! */
405+
}
406+
else
407+
q = &p->next;
408+
}
409+
}
410+
380411
#endif /* Py_HAVE_NATIVE_TLS */

0 commit comments

Comments
 (0)