summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2013-05-05 21:47:09 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2013-05-05 21:47:09 (GMT)
commit8408cea0cdc0ccd5900acd99a9a51dd9161ae319 (patch)
tree0dcb39ac0cf5fc5e293941763a31bd2472dd004b /Python/ceval.c
parent39b17c513ae7b9baecdc8292876683647186fee4 (diff)
downloadcpython-8408cea0cdc0ccd5900acd99a9a51dd9161ae319.zip
cpython-8408cea0cdc0ccd5900acd99a9a51dd9161ae319.tar.gz
cpython-8408cea0cdc0ccd5900acd99a9a51dd9161ae319.tar.bz2
Issue #17094: Clear stale thread states after fork().
Note that this is a potentially disruptive change since it may release some system resources which would otherwise remain perpetually alive (e.g. database connections kept in thread-local storage).
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index cbc0fab..d32b6fb 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -362,29 +362,28 @@ PyEval_ReleaseThread(PyThreadState *tstate)
drop_gil(tstate);
}
-/* 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.) */
+/* This function is called from PyOS_AfterFork to destroy all threads which are
+ * not running in the child process, and clear internal locks which might be
+ * held by those threads. (This could also be done using pthread_atfork
+ * mechanism, at least for the pthreads implementation.) */
void
PyEval_ReInitThreads(void)
{
_Py_IDENTIFIER(_after_fork);
PyObject *threading, *result;
- PyThreadState *tstate = PyThreadState_GET();
+ PyThreadState *current_tstate = PyThreadState_GET();
if (!gil_created())
return;
recreate_gil();
pending_lock = PyThread_allocate_lock();
- take_gil(tstate);
+ take_gil(current_tstate);
main_thread = PyThread_get_thread_ident();
/* Update the threading module with the new state.
*/
- tstate = PyThreadState_GET();
- threading = PyMapping_GetItemString(tstate->interp->modules,
+ threading = PyMapping_GetItemString(current_tstate->interp->modules,
"threading");
if (threading == NULL) {
/* threading not imported */
@@ -397,6 +396,9 @@ PyEval_ReInitThreads(void)
else
Py_DECREF(result);
Py_DECREF(threading);
+
+ /* Destroy all threads except the current one */
+ _PyThreadState_DeleteExcept(current_tstate);
}
#else