summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2018-05-15 13:56:18 (GMT)
committerGitHub <noreply@github.com>2018-05-15 13:56:18 (GMT)
commit6bd0c476c58ca0046969f70dc2a4e4dfb3268062 (patch)
tree0d03c95e5426fc5912d836443a93c7ecf5641851 /Python
parent5c7e079158db869c9ede1ac9b5b9735091d3ffb6 (diff)
downloadcpython-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.c258
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