diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2018-06-02 00:45:20 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-02 00:45:20 (GMT) |
commit | 63799136e6c0491bb5d6f4a234d5a775db3458db (patch) | |
tree | 73b6425dbddf05b042b2c48f9053232348fd3e0f /Python | |
parent | 29996a1c4e8bd6dde6adce2b44d11a0982a47a3a (diff) | |
download | cpython-63799136e6c0491bb5d6f4a234d5a775db3458db.zip cpython-63799136e6c0491bb5d6f4a234d5a775db3458db.tar.gz cpython-63799136e6c0491bb5d6f4a234d5a775db3458db.tar.bz2 |
bpo-33615: Re-enable a subinterpreter test. (gh-7251)
For bpo-32604 I added extra subinterpreter-related tests (see #6914), which caused a few buildbots to crash. This patch fixes the crash by ensuring that refcounts in channels are handled properly.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/pystate.c | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/Python/pystate.c b/Python/pystate.c index 4534c47..629598e 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1205,7 +1205,6 @@ _PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) } // Fill in the blanks and validate the result. - Py_XINCREF(data->obj); data->interp = interp->id; if (_check_xidata(data) != 0) { _PyCrossInterpreterData_Release(data); @@ -1215,6 +1214,40 @@ _PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) return 0; } +static void +_release_xidata(void *arg) +{ + _PyCrossInterpreterData *data = (_PyCrossInterpreterData *)arg; + if (data->free != NULL) { + data->free(data->data); + } + Py_XDECREF(data->obj); +} + +static void +_call_in_interpreter(PyInterpreterState *interp, + void (*func)(void *), void *arg) +{ + /* We would use Py_AddPendingCall() if it weren't specific to the + * main interpreter (see bpo-33608). In the meantime we take a + * naive approach. + */ + 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); + } + + func(arg); + + // Switch back. + if (save_tstate != NULL) { + PyThreadState_Swap(save_tstate); + } +} + void _PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) { @@ -1233,24 +1266,8 @@ _PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) return; } - 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) { - data->free(data->data); - } - Py_XDECREF(data->obj); - - // Switch back. - if (save_tstate != NULL) { - PyThreadState_Swap(save_tstate); - } + _call_in_interpreter(interp, _release_xidata, data); } PyObject * @@ -1355,6 +1372,7 @@ _bytes_shared(PyObject *obj, _PyCrossInterpreterData *data) return -1; } data->data = (void *)shared; + Py_INCREF(obj); data->obj = obj; // Will be "released" (decref'ed) when data released. data->new_object = _new_bytes_object; data->free = PyMem_Free; @@ -1382,6 +1400,7 @@ _str_shared(PyObject *obj, _PyCrossInterpreterData *data) shared->buffer = PyUnicode_DATA(obj); shared->len = PyUnicode_GET_LENGTH(obj) - 1; data->data = (void *)shared; + Py_INCREF(obj); data->obj = obj; // Will be "released" (decref'ed) when data released. data->new_object = _new_str_object; data->free = PyMem_Free; |