summaryrefslogtreecommitdiffstats
path: root/Python/pystate.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/pystate.c')
-rw-r--r--Python/pystate.c57
1 files changed, 34 insertions, 23 deletions
diff --git a/Python/pystate.c b/Python/pystate.c
index 8fff161..93f0ce7 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -39,6 +39,7 @@ extern "C" {
/* Forward declarations */
static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate);
+static void _PyThreadState_Delete(PyThreadState *tstate, int check_current);
static PyStatus
@@ -295,13 +296,13 @@ PyInterpreterState_Clear(PyInterpreterState *interp)
static void
-zapthreads(PyInterpreterState *interp)
+zapthreads(PyInterpreterState *interp, int check_current)
{
- PyThreadState *p;
+ PyThreadState *tstate;
/* No need to lock the mutex here because this should only happen
when the threads are all really dead (XXX famous last words). */
- while ((p = interp->tstate_head) != NULL) {
- PyThreadState_Delete(p);
+ while ((tstate = interp->tstate_head) != NULL) {
+ _PyThreadState_Delete(tstate, check_current);
}
}
@@ -311,7 +312,11 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
{
_PyRuntimeState *runtime = interp->runtime;
struct pyinterpreters *interpreters = &runtime->interpreters;
- zapthreads(interp);
+ zapthreads(interp, 0);
+
+ /* Delete current thread. After this, many C API calls become crashy. */
+ _PyThreadState_Swap(&runtime->gilstate, NULL);
+
HEAD_LOCK(runtime);
PyInterpreterState **p;
for (p = &interpreters->head; ; p = &(*p)->next) {
@@ -367,7 +372,7 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime)
}
PyInterpreterState_Clear(interp); // XXX must activate?
- zapthreads(interp);
+ zapthreads(interp, 1);
if (interp->id_mutex != NULL) {
PyThread_free_lock(interp->id_mutex);
}
@@ -793,7 +798,8 @@ PyThreadState_Clear(PyThreadState *tstate)
/* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */
static void
-tstate_delete_common(PyThreadState *tstate)
+tstate_delete_common(PyThreadState *tstate,
+ struct _gilstate_runtime_state *gilstate)
{
_PyRuntimeState *runtime = tstate->interp->runtime;
if (tstate == NULL) {
@@ -815,22 +821,32 @@ tstate_delete_common(PyThreadState *tstate)
tstate->on_delete(tstate->on_delete_data);
}
PyMem_RawFree(tstate);
-}
-
-void
-PyThreadState_Delete(PyThreadState *tstate)
-{
- struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
- if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) {
- Py_FatalError("PyThreadState_Delete: tstate is still current");
- }
if (gilstate->autoInterpreterState &&
PyThread_tss_get(&gilstate->autoTSSkey) == tstate)
{
PyThread_tss_set(&gilstate->autoTSSkey, NULL);
}
- tstate_delete_common(tstate);
+}
+
+
+static void
+_PyThreadState_Delete(PyThreadState *tstate, int check_current)
+{
+ struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
+ if (check_current) {
+ if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) {
+ Py_FatalError("PyThreadState_Delete: tstate is still current");
+ }
+ }
+ tstate_delete_common(tstate, gilstate);
+}
+
+
+void
+PyThreadState_Delete(PyThreadState *tstate)
+{
+ _PyThreadState_Delete(tstate, 1);
}
@@ -842,12 +858,7 @@ _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime)
if (tstate == NULL)
Py_FatalError(
"PyThreadState_DeleteCurrent: no current tstate");
- tstate_delete_common(tstate);
- if (gilstate->autoInterpreterState &&
- PyThread_tss_get(&gilstate->autoTSSkey) == tstate)
- {
- PyThread_tss_set(&gilstate->autoTSSkey, NULL);
- }
+ tstate_delete_common(tstate, gilstate);
_PyRuntimeGILState_SetThreadState(gilstate, NULL);
PyEval_ReleaseLock();
}