Esempio n. 1
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;
    }

    // "Release" the data and/or the object.
    _call_in_interpreter(interp, _release_xidata, data);
}
Esempio n. 2
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);
    }
}
Esempio n. 3
0
void
_PyCrossInterpreterData_Release(_PyCrossInterpreterData *data)
{
    if (data->data == NULL && data->obj == NULL) {
        // Nothing to release!
        return;
    }

    // Get 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;
    }
    // XXX There's an ever-so-slight race here...
    if (interp->finalizing) {
        // XXX Someone leaked some memory...
        return;
    }

    // "Release" the data and/or the object.
    _PyCrossInterpreterData *copied = PyMem_Malloc(sizeof(_PyCrossInterpreterData));
    if (copied == NULL) {
        PyErr_SetString(PyExc_MemoryError,
                        "Not enough memory to preserve cross-interpreter data");
        PyErr_Print();
        return;
    }
    memcpy(copied, data, sizeof(_PyCrossInterpreterData));
    if (_Py_AddPendingCall(interp, 0, _release_xidata, copied) != 0) {
        // XXX Queue full or couldn't get lock.  Try again somehow?
    }
}