diff options
| author | Eric Snow <ericsnowcurrently@gmail.com> | 2018-05-15 13:56:18 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-05-15 13:56:18 (GMT) |
| commit | 6bd0c476c58ca0046969f70dc2a4e4dfb3268062 (patch) | |
| tree | 0d03c95e5426fc5912d836443a93c7ecf5641851 /Python | |
| parent | 5c7e079158db869c9ede1ac9b5b9735091d3ffb6 (diff) | |
| download | cpython-6bd0c476c58ca0046969f70dc2a4e4dfb3268062.zip cpython-6bd0c476c58ca0046969f70dc2a4e4dfb3268062.tar.gz cpython-6bd0c476c58ca0046969f70dc2a4e4dfb3268062.tar.bz2 | |
bpo-32604: Remove xid registry. (#6813)
Remove the interpreters testing helper (and xid registry).
Diffstat (limited to 'Python')
| -rw-r--r-- | Python/pystate.c | 258 |
1 files changed, 0 insertions, 258 deletions
diff --git a/Python/pystate.c b/Python/pystate.c index 140d2fb..7750f4c 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -56,11 +56,6 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime) } runtime->interpreters.next_id = -1; - runtime->xidregistry.mutex = PyThread_allocate_lock(); - if (runtime->xidregistry.mutex == NULL) { - return _Py_INIT_ERR("Can't initialize threads for cross-interpreter data registry"); - } - return _Py_INIT_OK(); } @@ -1128,259 +1123,6 @@ PyGILState_Release(PyGILState_STATE oldstate) } -/**************************/ -/* cross-interpreter data */ -/**************************/ - -/* cross-interpreter data */ - -crossinterpdatafunc _PyCrossInterpreterData_Lookup(PyObject *); - -/* This is a separate func from _PyCrossInterpreterData_Lookup in order - to keep the registry code separate. */ -static crossinterpdatafunc -_lookup_getdata(PyObject *obj) -{ - crossinterpdatafunc getdata = _PyCrossInterpreterData_Lookup(obj); - if (getdata == NULL && PyErr_Occurred() == 0) - PyErr_Format(PyExc_ValueError, - "%S does not support cross-interpreter data", obj); - return getdata; -} - -int -_PyObject_CheckCrossInterpreterData(PyObject *obj) -{ - crossinterpdatafunc getdata = _lookup_getdata(obj); - if (getdata == NULL) { - return -1; - } - return 0; -} - -static int -_check_xidata(_PyCrossInterpreterData *data) -{ - // data->data can be anything, including NULL, so we don't check it. - - // data->obj may be NULL, so we don't check it. - - if (data->interp < 0) { - PyErr_SetString(PyExc_SystemError, "missing interp"); - return -1; - } - - if (data->new_object == NULL) { - PyErr_SetString(PyExc_SystemError, "missing new_object func"); - return -1; - } - - // data->free may be NULL, so we don't check it. - - return 0; -} - -int -_PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) -{ - PyThreadState *tstate = PyThreadState_Get(); - // PyThreadState_Get() aborts if lookup fails, so we don't need - // to check the result for NULL. - PyInterpreterState *interp = tstate->interp; - - // Reset data before re-populating. - *data = (_PyCrossInterpreterData){0}; - data->free = PyMem_RawFree; // Set a default that may be overridden. - - // Call the "getdata" func for the object. - Py_INCREF(obj); - crossinterpdatafunc getdata = _lookup_getdata(obj); - if (getdata == NULL) { - Py_DECREF(obj); - return -1; - } - int res = getdata(obj, data); - Py_DECREF(obj); - if (res != 0) { - return -1; - } - - // Fill in the blanks and validate the result. - Py_XINCREF(data->obj); - data->interp = interp->id; - if (_check_xidata(data) != 0) { - _PyCrossInterpreterData_Release(data); - return -1; - } - - return 0; -} - -void -_PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) -{ - if (data->data == NULL && data->obj == NULL) { - // Nothing to release! - return; - } - - // Switch to the original interpreter. - PyInterpreterState *interp = _PyInterpreterState_LookUpID(data->interp); - if (interp == NULL) { - // The intepreter was already destroyed. - if (data->free != NULL) { - // XXX Someone leaked some memory... - } - 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); - } -} - -PyObject * -_PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *data) -{ - return data->new_object(data); -} - -/* registry of {type -> crossinterpdatafunc} */ - -/* For now we use a global registry of shareable classes. An - alternative would be to add a tp_* slot for a class's - crossinterpdatafunc. It would be simpler and more efficient. */ - -static int -_register_xidata(PyTypeObject *cls, crossinterpdatafunc getdata) -{ - // Note that we effectively replace already registered classes - // rather than failing. - struct _xidregitem *newhead = PyMem_RawMalloc(sizeof(struct _xidregitem)); - if (newhead == NULL) - return -1; - newhead->cls = cls; - newhead->getdata = getdata; - newhead->next = _PyRuntime.xidregistry.head; - _PyRuntime.xidregistry.head = newhead; - return 0; -} - -static void _register_builtins_for_crossinterpreter_data(void); - -int -_PyCrossInterpreterData_Register_Class(PyTypeObject *cls, - crossinterpdatafunc getdata) -{ - if (!PyType_Check(cls)) { - PyErr_Format(PyExc_ValueError, "only classes may be registered"); - return -1; - } - if (getdata == NULL) { - PyErr_Format(PyExc_ValueError, "missing 'getdata' func"); - return -1; - } - - // Make sure the class isn't ever deallocated. - Py_INCREF((PyObject *)cls); - - PyThread_acquire_lock(_PyRuntime.xidregistry.mutex, WAIT_LOCK); - if (_PyRuntime.xidregistry.head == NULL) { - _register_builtins_for_crossinterpreter_data(); - } - int res = _register_xidata(cls, getdata); - PyThread_release_lock(_PyRuntime.xidregistry.mutex); - return res; -} - -crossinterpdatafunc -_PyCrossInterpreterData_Lookup(PyObject *obj) -{ - PyObject *cls = PyObject_Type(obj); - crossinterpdatafunc getdata = NULL; - PyThread_acquire_lock(_PyRuntime.xidregistry.mutex, WAIT_LOCK); - struct _xidregitem *cur = _PyRuntime.xidregistry.head; - if (cur == NULL) { - _register_builtins_for_crossinterpreter_data(); - cur = _PyRuntime.xidregistry.head; - } - for(; cur != NULL; cur = cur->next) { - if (cur->cls == (PyTypeObject *)cls) { - getdata = cur->getdata; - break; - } - } - Py_DECREF(cls); - PyThread_release_lock(_PyRuntime.xidregistry.mutex); - return getdata; -} - -/* cross-interpreter data for builtin types */ - -static PyObject * -_new_bytes_object(_PyCrossInterpreterData *data) -{ - return PyBytes_FromString((char *)(data->data)); -} - -static int -_bytes_shared(PyObject *obj, _PyCrossInterpreterData *data) -{ - data->data = (void *)(PyBytes_AS_STRING(obj)); - data->obj = obj; // Will be "released" (decref'ed) when data released. - data->new_object = _new_bytes_object; - data->free = NULL; // Do not free the data (it belongs to the object). - return 0; -} - -static PyObject * -_new_none_object(_PyCrossInterpreterData *data) -{ - // XXX Singleton refcounts are problematic across interpreters... - Py_INCREF(Py_None); - return Py_None; -} - -static int -_none_shared(PyObject *obj, _PyCrossInterpreterData *data) -{ - data->data = NULL; - // data->obj remains NULL - data->new_object = _new_none_object; - data->free = NULL; // There is nothing to free. - return 0; -} - -static void -_register_builtins_for_crossinterpreter_data(void) -{ - // None - if (_register_xidata((PyTypeObject *)PyObject_Type(Py_None), _none_shared) != 0) { - Py_FatalError("could not register None for cross-interpreter sharing"); - } - - // bytes - if (_register_xidata(&PyBytes_Type, _bytes_shared) != 0) { - Py_FatalError("could not register bytes for cross-interpreter sharing"); - } -} - - #ifdef __cplusplus } #endif |
