diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2013-05-05 21:47:09 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2013-05-05 21:47:09 (GMT) |
commit | 8408cea0cdc0ccd5900acd99a9a51dd9161ae319 (patch) | |
tree | 0dcb39ac0cf5fc5e293941763a31bd2472dd004b /Python/ceval.c | |
parent | 39b17c513ae7b9baecdc8292876683647186fee4 (diff) | |
download | cpython-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.c | 18 |
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 |