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.
This commit is contained in:
Eric Snow 2018-06-01 18:45:20 -06:00 committed by GitHub
parent 29996a1c4e
commit 63799136e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 23 deletions

View file

@ -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;