summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Modules/signalmodule.c1
-rw-r--r--Parser/intrcheck.c3
-rw-r--r--Python/ceval.c19
3 files changed, 23 insertions, 0 deletions
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index 4b9876f..368955e 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -667,6 +667,7 @@ void
PyOS_AfterFork(void)
{
#ifdef WITH_THREAD
+ PyEval_ReInitThreads();
main_thread = PyThread_get_thread_ident();
main_pid = getpid();
#endif
diff --git a/Parser/intrcheck.c b/Parser/intrcheck.c
index 519f404..d20ed61 100644
--- a/Parser/intrcheck.c
+++ b/Parser/intrcheck.c
@@ -195,4 +195,7 @@ PyOS_InterruptOccurred(void)
void
PyOS_AfterFork(void)
{
+#ifdef WITH_THREAD
+ PyEval_ReInitThreads();
+#endif
}
diff --git a/Python/ceval.c b/Python/ceval.c
index 3488b9c..2648add 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -142,6 +142,25 @@ PyEval_ReleaseThread(PyThreadState *tstate)
Py_FatalError("PyEval_ReleaseThread: wrong thread state");
PyThread_release_lock(interpreter_lock);
}
+
+/* This function is called from PyOS_AfterFork to ensure that newly
+ created child processes don't hold locks referring to threads which
+ are not running in the child process. (This could also be done using
+ pthread_atfork mechanism, at least for the pthreads implementation.) */
+
+void
+PyEval_ReInitThreads(void)
+{
+ if (!interpreter_lock)
+ return;
+ /*XXX Can't use PyThread_free_lock here because it does too
+ much error-checking. Doing this cleanly would require
+ adding a new function to each thread_*.h. Instead, just
+ create a new lock and waste a little bit of memory */
+ interpreter_lock = PyThread_allocate_lock();
+ PyThread_acquire_lock(interpreter_lock, 1);
+ main_thread = PyThread_get_thread_ident();
+}
#endif
/* Functions save_thread and restore_thread are always defined so