Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add _PyXIData_lookup_context_t.
  • Loading branch information
ericsnowcurrently committed Nov 11, 2024
commit ecb2d459081c91668655893b41936df0f59e944b
23 changes: 20 additions & 3 deletions Include/internal/pycore_crossinterp.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,26 @@ typedef int (*xidatafunc)(PyThreadState *tstate, PyObject *, _PyXIData_t *);

typedef struct _xid_lookup_state _PyXIData_lookup_t;

PyAPI_FUNC(xidatafunc) _PyXIData_Lookup(PyObject *);
PyAPI_FUNC(int) _PyObject_CheckXIData(PyObject *);
PyAPI_FUNC(int) _PyObject_GetXIData(PyObject *, _PyXIData_t *);
typedef struct {
_PyXIData_lookup_t *global;
_PyXIData_lookup_t *local;
PyObject *PyExc_NotShareableError;
} _PyXIData_lookup_context_t;

PyAPI_FUNC(int) _PyXIData_GetLookupContext(
PyInterpreterState *,
_PyXIData_lookup_context_t *);

PyAPI_FUNC(xidatafunc) _PyXIData_Lookup(
_PyXIData_lookup_context_t *,
PyObject *);
PyAPI_FUNC(int) _PyObject_CheckXIData(
_PyXIData_lookup_context_t *,
PyObject *);
PyAPI_FUNC(int) _PyObject_GetXIData(
_PyXIData_lookup_context_t *,
PyObject *,
_PyXIData_t *);


/* using cross-interpreter data */
Expand Down
9 changes: 7 additions & 2 deletions Include/internal/pycore_crossinterp_data_registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@ typedef struct {
_PyXIData_regitem_t *head;
} _PyXIData_registry_t;

PyAPI_FUNC(int) _PyXIData_RegisterClass(PyTypeObject *, xidatafunc);
PyAPI_FUNC(int) _PyXIData_UnregisterClass(PyTypeObject *);
PyAPI_FUNC(int) _PyXIData_RegisterClass(
_PyXIData_lookup_context_t *,
PyTypeObject *,
xidatafunc);
PyAPI_FUNC(int) _PyXIData_UnregisterClass(
_PyXIData_lookup_context_t *,
PyTypeObject *);

struct _xid_lookup_state {
// XXX Remove this field once we have a tp_* slot.
Expand Down
7 changes: 6 additions & 1 deletion Modules/_interpchannelsmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1758,6 +1758,11 @@ channel_send(_channels *channels, int64_t cid, PyObject *obj,
}
int64_t interpid = PyInterpreterState_GetID(interp);

_PyXIData_lookup_context_t ctx;
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
return -1;
}

// Look up the channel.
PyThread_type_lock mutex = NULL;
_channel_state *chan = NULL;
Expand All @@ -1779,7 +1784,7 @@ channel_send(_channels *channels, int64_t cid, PyObject *obj,
PyThread_release_lock(mutex);
return -1;
}
if (_PyObject_GetXIData(obj, data) != 0) {
if (_PyObject_GetXIData(&ctx, obj, data) != 0) {
PyThread_release_lock(mutex);
GLOBAL_FREE(data);
return -1;
Expand Down
11 changes: 8 additions & 3 deletions Modules/_interpqueuesmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1127,6 +1127,12 @@ queue_destroy(_queues *queues, int64_t qid)
static int
queue_put(_queues *queues, int64_t qid, PyObject *obj, int fmt, int unboundop)
{
PyInterpreterState *interp = PyInterpreterState_Get();
_PyXIData_lookup_context_t ctx;
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
return -1;
}

// Look up the queue.
_queue *queue = NULL;
int err = _queues_lookup(queues, qid, &queue);
Expand All @@ -1141,13 +1147,12 @@ queue_put(_queues *queues, int64_t qid, PyObject *obj, int fmt, int unboundop)
_queue_unmark_waiter(queue, queues->mutex);
return -1;
}
if (_PyObject_GetXIData(obj, data) != 0) {
if (_PyObject_GetXIData(&ctx, obj, data) != 0) {
_queue_unmark_waiter(queue, queues->mutex);
GLOBAL_FREE(data);
return -1;
}
assert(_PyXIData_INTERPID(data) == \
PyInterpreterState_GetID(PyInterpreterState_Get()));
assert(_PyXIData_INTERPID(data) == PyInterpreterState_GetID(interp));

// Add the data to the queue.
int64_t interpid = -1; // _queueitem_init() will set it.
Expand Down
15 changes: 12 additions & 3 deletions Modules/_interpreters_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,24 @@
static int
ensure_xid_class(PyTypeObject *cls, xidatafunc getdata)
{
//assert(cls->tp_flags & Py_TPFLAGS_HEAPTYPE);
return _PyXIData_RegisterClass(cls, getdata);
PyInterpreterState *interp = PyInterpreterState_Get();
_PyXIData_lookup_context_t ctx;
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
return -1;
}
return _PyXIData_RegisterClass(&ctx, cls, getdata);
}

#ifdef REGISTERS_HEAP_TYPES
static int
clear_xid_class(PyTypeObject *cls)
{
return _PyXIData_UnregisterClass(cls);
PyInterpreterState *interp = PyInterpreterState_Get();
_PyXIData_lookup_context_t ctx;
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
return -1;
}
return _PyXIData_UnregisterClass(&ctx, cls);
}
#endif

Expand Down
17 changes: 13 additions & 4 deletions Modules/_interpretersmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1186,7 +1186,13 @@ object_is_shareable(PyObject *self, PyObject *args, PyObject *kwds)
return NULL;
}

if (_PyObject_CheckXIData(obj) == 0) {
PyInterpreterState *interp = PyInterpreterState_Get();
_PyXIData_lookup_context_t ctx;
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
return NULL;
}

if (_PyObject_CheckXIData(&ctx, obj) == 0) {
Py_RETURN_TRUE;
}
PyErr_Clear();
Expand Down Expand Up @@ -1485,6 +1491,11 @@ module_exec(PyObject *mod)
PyInterpreterState *interp = PyInterpreterState_Get();
module_state *state = get_module_state(mod);

_PyXIData_lookup_context_t ctx;
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
return -1;
}

#define ADD_WHENCE(NAME) \
if (PyModule_AddIntConstant(mod, "WHENCE_" #NAME, \
_PyInterpreterState_WHENCE_##NAME) < 0) \
Expand All @@ -1506,9 +1517,7 @@ module_exec(PyObject *mod)
if (PyModule_AddType(mod, (PyTypeObject *)PyExc_InterpreterNotFoundError) < 0) {
goto error;
}
PyObject *PyExc_NotShareableError = \
_PyXI_GET_STATE(interp)->exceptions.PyExc_NotShareableError;
if (PyModule_AddType(mod, (PyTypeObject *)PyExc_NotShareableError) < 0) {
if (PyModule_AddType(mod, (PyTypeObject *)ctx.PyExc_NotShareableError) < 0) {
goto error;
}

Expand Down
8 changes: 7 additions & 1 deletion Modules/_testinternalcapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1797,6 +1797,12 @@ _xid_capsule_destructor(PyObject *capsule)
static PyObject *
get_crossinterp_data(PyObject *self, PyObject *args)
{
PyInterpreterState *interp = PyInterpreterState_Get();
_PyXIData_lookup_context_t ctx;
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
return NULL;
}

PyObject *obj = NULL;
if (!PyArg_ParseTuple(args, "O:get_crossinterp_data", &obj)) {
return NULL;
Expand All @@ -1806,7 +1812,7 @@ get_crossinterp_data(PyObject *self, PyObject *args)
if (data == NULL) {
return NULL;
}
if (_PyObject_GetXIData(obj, data) != 0) {
if (_PyObject_GetXIData(&ctx, obj, data) != 0) {
_PyXIData_Free(data);
return NULL;
}
Expand Down
55 changes: 34 additions & 21 deletions Python/crossinterp.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ _Py_CallInInterpreterAndRawFree(PyInterpreterState *interp,

static void xid_lookup_init(_PyXIData_lookup_t *);
static void xid_lookup_fini(_PyXIData_lookup_t *);
static xidatafunc lookup_getdata(PyInterpreterState *, PyObject *);
static xidatafunc lookup_getdata(_PyXIData_lookup_context_t *, PyObject *);
#include "crossinterp_data_lookup.h"


Expand Down Expand Up @@ -198,9 +198,9 @@ _check_xidata(PyThreadState *tstate, _PyXIData_t *data)
}

static inline void
_set_xid_lookup_failure(_PyXI_state_t *state, PyObject *obj, const char *msg)
_set_xid_lookup_failure(dlcontext_t *ctx, PyObject *obj, const char *msg)
{
PyObject *exctype = state->exceptions.PyExc_NotShareableError;
PyObject *exctype = ctx->PyExc_NotShareableError;
assert(exctype != NULL);
if (msg != NULL) {
assert(obj == NULL);
Expand All @@ -217,38 +217,36 @@ _set_xid_lookup_failure(_PyXI_state_t *state, PyObject *obj, const char *msg)
}

int
_PyObject_CheckXIData(PyObject *obj)
_PyObject_CheckXIData(_PyXIData_lookup_context_t *ctx, PyObject *obj)
{
PyInterpreterState *interp = PyInterpreterState_Get();
_PyXI_state_t *state = _PyXI_GET_STATE(interp);
xidatafunc getdata = lookup_getdata(interp, obj);
xidatafunc getdata = lookup_getdata(ctx, obj);
if (getdata == NULL) {
if (!PyErr_Occurred()) {
_set_xid_lookup_failure(state, obj, NULL);
_set_xid_lookup_failure(ctx, obj, NULL);
}
return -1;
}
return 0;
}

int
_PyObject_GetXIData(PyObject *obj, _PyXIData_t *data)
_PyObject_GetXIData(_PyXIData_lookup_context_t *ctx,
PyObject *obj, _PyXIData_t *data)
{
PyThreadState *tstate = PyThreadState_Get();
PyInterpreterState *interp = tstate->interp;
_PyXI_state_t *state = _PyXI_GET_STATE(interp);

// Reset data before re-populating.
*data = (_PyXIData_t){0};
_PyXIData_INTERPID(data) = -1;

// Call the "getdata" func for the object.
Py_INCREF(obj);
xidatafunc getdata = lookup_getdata(interp, obj);
xidatafunc getdata = lookup_getdata(ctx, obj);
if (getdata == NULL) {
Py_DECREF(obj);
if (!PyErr_Occurred()) {
_set_xid_lookup_failure(state, obj, NULL);
_set_xid_lookup_failure(ctx, obj, NULL);
}
return -1;
}
Expand Down Expand Up @@ -965,7 +963,8 @@ _PyXI_ClearExcInfo(_PyXI_excinfo *info)
static int
_PyXI_ApplyErrorCode(_PyXI_errcode code, PyInterpreterState *interp)
{
_PyXI_state_t *state;
dlcontext_t ctx;

assert(!PyErr_Occurred());
switch (code) {
case _PyXI_ERR_NO_ERROR: _Py_FALLTHROUGH;
Expand Down Expand Up @@ -996,8 +995,10 @@ _PyXI_ApplyErrorCode(_PyXI_errcode code, PyInterpreterState *interp)
"failed to apply namespace to __main__");
break;
case _PyXI_ERR_NOT_SHAREABLE:
state = _PyXI_GET_STATE(interp);
_set_xid_lookup_failure(state, NULL, NULL);
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
return -1;
}
_set_xid_lookup_failure(&ctx, NULL, NULL);
break;
default:
#ifdef Py_DEBUG
Expand Down Expand Up @@ -1059,8 +1060,11 @@ _PyXI_ApplyError(_PyXI_error *error)
}
else if (error->code == _PyXI_ERR_NOT_SHAREABLE) {
// Propagate the exception directly.
_PyXI_state_t *state = _PyXI_GET_STATE(error->interp);
_set_xid_lookup_failure(state, NULL, error->uncaught.msg);
dlcontext_t ctx;
if (_PyXIData_GetLookupContext(error->interp, &ctx) < 0) {
return NULL;
}
_set_xid_lookup_failure(&ctx, NULL, error->uncaught.msg);
}
else {
// Raise an exception corresponding to the code.
Expand Down Expand Up @@ -1147,7 +1151,12 @@ _sharednsitem_set_value(_PyXI_namespace_item *item, PyObject *value)
PyErr_NoMemory();
return -1;
}
if (_PyObject_GetXIData(value, item->data) != 0) {
PyInterpreterState *interp = PyInterpreterState_Get();
dlcontext_t ctx;
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
return -1;
}
if (_PyObject_GetXIData(&ctx, value, item->data) != 0) {
PyMem_RawFree(item->data);
item->data = NULL;
// The caller may want to propagate PyExc_NotShareableError
Expand Down Expand Up @@ -1605,9 +1614,13 @@ _propagate_not_shareable_error(_PyXI_session *session)
return;
}
PyInterpreterState *interp = PyInterpreterState_Get();
_PyXI_state_t *state = _PyXI_GET_STATE(interp);
assert(state->exceptions.PyExc_NotShareableError != NULL);
if (PyErr_ExceptionMatches(state->exceptions.PyExc_NotShareableError)) {
dlcontext_t ctx;
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
PyErr_FormatUnraisable(
"Exception ignored while propagating not shareable error");
return;
}
if (PyErr_ExceptionMatches(ctx.PyExc_NotShareableError)) {
// We want to propagate the exception directly.
session->_error_override = _PyXI_ERR_NOT_SHAREABLE;
session->error_override = &session->_error_override;
Expand Down
Loading