Issue #10517: After fork(), reinitialize the TLS used by the PyGILState_*

APIs, to avoid a crash with the pthread implementation in RHEL 5.  Patch
by Charles-François Natali.
This commit is contained in:
Antoine Pitrou 2011-04-27 19:28:05 +02:00
parent 43ae619925
commit 0c759febb6
4 changed files with 23 additions and 0 deletions

View file

@ -131,6 +131,7 @@ PyAPI_FUNC(void) PyThreadState_Clear(PyThreadState *);
PyAPI_FUNC(void) PyThreadState_Delete(PyThreadState *); PyAPI_FUNC(void) PyThreadState_Delete(PyThreadState *);
#ifdef WITH_THREAD #ifdef WITH_THREAD
PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void); PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void);
PyAPI_FUNC(void) _PyGILState_Reinit(void);
#endif #endif
PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void); PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void);

View file

@ -10,6 +10,10 @@ What's New in Python 3.2.1?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #10517: After fork(), reinitialize the TLS used by the PyGILState_*
APIs, to avoid a crash with the pthread implementation in RHEL 5. Patch
by Charles-François Natali.
- Issue #6780: fix starts/endswith error message to mention that tuples are - Issue #6780: fix starts/endswith error message to mention that tuples are
accepted too. accepted too.

View file

@ -991,6 +991,7 @@ void
PyOS_AfterFork(void) PyOS_AfterFork(void)
{ {
#ifdef WITH_THREAD #ifdef WITH_THREAD
_PyGILState_Reinit();
PyEval_ReInitThreads(); PyEval_ReInitThreads();
main_thread = PyThread_get_thread_ident(); main_thread = PyThread_get_thread_ident();
main_pid = getpid(); main_pid = getpid();

View file

@ -585,6 +585,23 @@ _PyGILState_Fini(void)
autoInterpreterState = NULL; autoInterpreterState = NULL;
} }
/* Reset the TLS key - called by PyOS_AfterFork.
* This should not be necessary, but some - buggy - pthread implementations
* don't flush TLS on fork, see issue #10517.
*/
void
_PyGILState_Reinit(void)
{
PyThreadState *tstate = PyGILState_GetThisThreadState();
PyThread_delete_key(autoTLSkey);
if ((autoTLSkey = PyThread_create_key()) == -1)
Py_FatalError("Could not allocate TLS entry");
/* re-associate the current thread state with the new key */
if (PyThread_set_key_value(autoTLSkey, (void *)tstate) < 0)
Py_FatalError("Couldn't create autoTLSkey mapping");
}
/* When a thread state is created for a thread by some mechanism other than /* When a thread state is created for a thread by some mechanism other than
PyGILState_Ensure, it's important that the GILState machinery knows about PyGILState_Ensure, it's important that the GILState machinery knows about
it so it doesn't try to create another thread state for the thread (this is it so it doesn't try to create another thread state for the thread (this is