summaryrefslogtreecommitdiff
path: root/Python/pystate.c
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2018-09-14 14:17:20 -0700
committerGitHub <noreply@github.com>2018-09-14 14:17:20 -0700
commit5903296045b586b9cd1fce0b1e02caf896028d1d (patch)
tree99e8900633096060e931980d52e063c044870d3c /Python/pystate.c
parent3faaa8857a42a36383bb18425444e597fc876797 (diff)
downloadcpython-git-5903296045b586b9cd1fce0b1e02caf896028d1d.tar.gz
bpo-34651: Only allow the main interpreter to fork. (gh-9279)
When os.fork() is called (on platforms that support it) all threads but the current one are destroyed in the child process. Consequently we must ensure that all but the associated interpreter are likewise destroyed. The main interpreter is critical for runtime operation, so we must ensure that fork only happens in the main interpreter. https://bugs.python.org/issue34651
Diffstat (limited to 'Python/pystate.c')
-rw-r--r--Python/pystate.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/Python/pystate.c b/Python/pystate.c
index 7d63f4febb..7b3d3d4c90 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -268,6 +268,44 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
}
+/*
+ * Delete all interpreter states except the main interpreter. If there
+ * is a current interpreter state, it *must* be the main interpreter.
+ */
+void
+_PyInterpreterState_DeleteExceptMain()
+{
+ PyThreadState *tstate = PyThreadState_Swap(NULL);
+ if (tstate != NULL && tstate->interp != _PyRuntime.interpreters.main) {
+ Py_FatalError("PyInterpreterState_DeleteExceptMain: not main interpreter");
+ }
+
+ HEAD_LOCK();
+ PyInterpreterState *interp = _PyRuntime.interpreters.head;
+ _PyRuntime.interpreters.head = NULL;
+ for (; interp != NULL; interp = interp->next) {
+ if (interp == _PyRuntime.interpreters.main) {
+ _PyRuntime.interpreters.main->next = NULL;
+ _PyRuntime.interpreters.head = interp;
+ continue;
+ }
+
+ PyInterpreterState_Clear(interp); // XXX must activate?
+ zapthreads(interp);
+ if (interp->id_mutex != NULL) {
+ PyThread_free_lock(interp->id_mutex);
+ }
+ PyMem_RawFree(interp);
+ }
+ HEAD_UNLOCK();
+
+ if (_PyRuntime.interpreters.head == NULL) {
+ Py_FatalError("PyInterpreterState_DeleteExceptMain: missing main");
+ }
+ PyThreadState_Swap(tstate);
+}
+
+
PyInterpreterState *
_PyInterpreterState_Get(void)
{