mirror of
https://github.com/python/cpython.git
synced 2025-08-22 01:35:16 +00:00
Backport of r64212
Issue #1683: prevent forking from interfering in threading storage.
This commit is contained in:
parent
e9859df798
commit
8a64048a22
5 changed files with 39 additions and 0 deletions
|
@ -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_get_key_value(int);
|
||||||
PyAPI_FUNC(void) PyThread_delete_key_value(int key);
|
PyAPI_FUNC(void) PyThread_delete_key_value(int key);
|
||||||
|
|
||||||
|
/* Cleanup after a fork */
|
||||||
|
PyAPI_FUNC(void) PyThread_ReInitTLS(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,6 +12,8 @@ What's New in Python 2.5.3?
|
||||||
Core and builtins
|
Core and builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #1683: prevent forking from interfering in threading storage.
|
||||||
|
|
||||||
- Issue #4597: Fixed several opcodes that weren't always propagating
|
- Issue #4597: Fixed several opcodes that weren't always propagating
|
||||||
exceptions.
|
exceptions.
|
||||||
|
|
||||||
|
|
|
@ -693,5 +693,6 @@ PyOS_AfterFork(void)
|
||||||
main_thread = PyThread_get_thread_ident();
|
main_thread = PyThread_get_thread_ident();
|
||||||
main_pid = getpid();
|
main_pid = getpid();
|
||||||
_PyImport_ReInitLock();
|
_PyImport_ReInitLock();
|
||||||
|
PyThread_ReInitTLS();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
/* Check for interrupts */
|
/* Check for interrupts */
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
#include "pythread.h"
|
||||||
|
|
||||||
#ifdef QUICKWIN
|
#ifdef QUICKWIN
|
||||||
|
|
||||||
|
@ -172,5 +173,6 @@ PyOS_AfterFork(void)
|
||||||
{
|
{
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
PyEval_ReInitThreads();
|
PyEval_ReInitThreads();
|
||||||
|
PyThread_ReInitTLS();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -391,4 +391,35 @@ PyThread_delete_key_value(int key)
|
||||||
PyThread_release_lock(keymutex);
|
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 */
|
#endif /* Py_HAVE_NATIVE_TLS */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue