diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2018-02-17 01:53:40 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-17 01:53:40 (GMT) |
commit | 4c6955e2b0ccf88c705f8d1fac685a8e65f9699e (patch) | |
tree | 56d0f3ce551117d3630c6efad21244385cbd9697 /Python | |
parent | bd093355a6aaf2f4ca3ed153e195da57870a55eb (diff) | |
download | cpython-4c6955e2b0ccf88c705f8d1fac685a8e65f9699e.zip cpython-4c6955e2b0ccf88c705f8d1fac685a8e65f9699e.tar.gz cpython-4c6955e2b0ccf88c705f8d1fac685a8e65f9699e.tar.bz2 |
bpo-32604: Clean up created subinterpreters before runtime finalization. (gh-5709)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/pystate.c | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/Python/pystate.c b/Python/pystate.c index 8dbda73..8cbf1fa 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -125,7 +125,8 @@ PyInterpreterState_New(void) return NULL; } - + interp->id_refcount = -1; + interp->id_mutex = NULL; interp->modules = NULL; interp->modules_by_index = NULL; interp->sysdict = NULL; @@ -247,6 +248,9 @@ PyInterpreterState_Delete(PyInterpreterState *interp) Py_FatalError("PyInterpreterState_Delete: remaining subinterpreters"); } HEAD_UNLOCK(); + if (interp->id_mutex != NULL) { + PyThread_free_lock(interp->id_mutex); + } PyMem_RawFree(interp); } @@ -284,6 +288,58 @@ error: return NULL; } + +int +_PyInterpreterState_IDInitref(PyInterpreterState *interp) +{ + if (interp->id_mutex != NULL) { + return 0; + } + interp->id_mutex = PyThread_allocate_lock(); + if (interp->id_mutex == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "failed to create init interpreter ID mutex"); + return -1; + } + interp->id_refcount = 0; + return 0; +} + + +void +_PyInterpreterState_IDIncref(PyInterpreterState *interp) +{ + if (interp->id_mutex == NULL) { + return; + } + PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); + interp->id_refcount += 1; + PyThread_release_lock(interp->id_mutex); +} + + +void +_PyInterpreterState_IDDecref(PyInterpreterState *interp) +{ + if (interp->id_mutex == NULL) { + return; + } + PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); + assert(interp->id_refcount != 0); + interp->id_refcount -= 1; + int64_t refcount = interp->id_refcount; + PyThread_release_lock(interp->id_mutex); + + if (refcount == 0) { + PyThreadState *tstate, *save_tstate; + tstate = PyInterpreterState_ThreadHead(interp); + save_tstate = PyThreadState_Swap(tstate); + Py_EndInterpreter(tstate); + PyThreadState_Swap(save_tstate); + } +} + + /* Default implementation for _PyThreadState_GetFrame */ static struct _frame * threadstate_getframe(PyThreadState *self) |