summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2018-02-20 23:30:17 (GMT)
committerGitHub <noreply@github.com>2018-02-20 23:30:17 (GMT)
commitf53d9f2778a87bdd48eb9030f782a4ebf9e7622f (patch)
tree42d0046cdda94825c800ed17db78f85c79d50bbf /Python
parent80d20b918bd8a882043c493a7f958333ecb41727 (diff)
downloadcpython-f53d9f2778a87bdd48eb9030f782a4ebf9e7622f.zip
cpython-f53d9f2778a87bdd48eb9030f782a4ebf9e7622f.tar.gz
cpython-f53d9f2778a87bdd48eb9030f782a4ebf9e7622f.tar.bz2
bpo-32604: Swap threads only if the interpreter is different. (gh-5778)
The CPython runtime assumes that there is a one-to-one relationship (for a given interpreter) between PyThreadState and OS threads. Sending and receiving on a channel in the same interpreter was causing crashes because of this (specifically due to a check in PyThreadState_Swap()). The solution is to not switch threads if the interpreter is the same.
Diffstat (limited to 'Python')
-rw-r--r--Python/pystate.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/Python/pystate.c b/Python/pystate.c
index 8cbf1fa..a87801f 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -331,9 +331,10 @@ _PyInterpreterState_IDDecref(PyInterpreterState *interp)
PyThread_release_lock(interp->id_mutex);
if (refcount == 0) {
- PyThreadState *tstate, *save_tstate;
- tstate = PyInterpreterState_ThreadHead(interp);
- save_tstate = PyThreadState_Swap(tstate);
+ // XXX Using the "head" thread isn't strictly correct.
+ PyThreadState *tstate = PyInterpreterState_ThreadHead(interp);
+ // XXX Possible GILState issues?
+ PyThreadState *save_tstate = PyThreadState_Swap(tstate);
Py_EndInterpreter(tstate);
PyThreadState_Swap(save_tstate);
}
@@ -1213,8 +1214,14 @@ _PyCrossInterpreterData_Release(_PyCrossInterpreterData *data)
}
return;
}
- PyThreadState *tstate = PyInterpreterState_ThreadHead(interp);
- PyThreadState *save_tstate = PyThreadState_Swap(tstate);
+
+ PyThreadState *save_tstate = NULL;
+ if (interp != PyThreadState_Get()->interp) {
+ // XXX Using the "head" thread isn't strictly correct.
+ PyThreadState *tstate = PyInterpreterState_ThreadHead(interp);
+ // XXX Possible GILState issues?
+ save_tstate = PyThreadState_Swap(tstate);
+ }
// "Release" the data and/or the object.
if (data->free != NULL) {
@@ -1223,8 +1230,9 @@ _PyCrossInterpreterData_Release(_PyCrossInterpreterData *data)
Py_XDECREF(data->obj);
// Switch back.
- if (save_tstate != NULL)
+ if (save_tstate != NULL) {
PyThreadState_Swap(save_tstate);
+ }
}
PyObject *