Skip to content

Commit 37b4768

Browse files
ericsnowcurrentlyebonnal
authored andcommitted
pythongh-76785: Improved Subinterpreters Compatibility with 3.12 (2/2) (pythongh-126707)
These changes makes it easier to backport the _interpreters, _interpqueues, and _interpchannels modules to Python 3.12. This involves the following: * add the _PyXI_GET_STATE() and _PyXI_GET_GLOBAL_STATE() macros * add _PyXIData_lookup_context_t and _PyXIData_GetLookupContext() * add _Py_xi_state_init() and _Py_xi_state_fini()
1 parent f12dc2a commit 37b4768

9 files changed

+247
-91
lines changed

Include/internal/pycore_crossinterp.h

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,26 @@ typedef int (*xidatafunc)(PyThreadState *tstate, PyObject *, _PyXIData_t *);
100100

101101
typedef struct _xid_lookup_state _PyXIData_lookup_t;
102102

103-
PyAPI_FUNC(xidatafunc) _PyXIData_Lookup(PyObject *);
104-
PyAPI_FUNC(int) _PyObject_CheckXIData(PyObject *);
105-
PyAPI_FUNC(int) _PyObject_GetXIData(PyObject *, _PyXIData_t *);
103+
typedef struct {
104+
_PyXIData_lookup_t *global;
105+
_PyXIData_lookup_t *local;
106+
PyObject *PyExc_NotShareableError;
107+
} _PyXIData_lookup_context_t;
108+
109+
PyAPI_FUNC(int) _PyXIData_GetLookupContext(
110+
PyInterpreterState *,
111+
_PyXIData_lookup_context_t *);
112+
113+
PyAPI_FUNC(xidatafunc) _PyXIData_Lookup(
114+
_PyXIData_lookup_context_t *,
115+
PyObject *);
116+
PyAPI_FUNC(int) _PyObject_CheckXIData(
117+
_PyXIData_lookup_context_t *,
118+
PyObject *);
119+
PyAPI_FUNC(int) _PyObject_GetXIData(
120+
_PyXIData_lookup_context_t *,
121+
PyObject *,
122+
_PyXIData_t *);
106123

107124

108125
/* using cross-interpreter data */
@@ -173,12 +190,20 @@ typedef struct {
173190
} exceptions;
174191
} _PyXI_state_t;
175192

193+
#define _PyXI_GET_GLOBAL_STATE(interp) (&(interp)->runtime->xi)
194+
#define _PyXI_GET_STATE(interp) (&(interp)->xi)
195+
196+
#ifndef Py_BUILD_CORE_MODULE
176197
extern PyStatus _PyXI_Init(PyInterpreterState *interp);
177198
extern void _PyXI_Fini(PyInterpreterState *interp);
178199
extern PyStatus _PyXI_InitTypes(PyInterpreterState *interp);
179200
extern void _PyXI_FiniTypes(PyInterpreterState *interp);
201+
#endif // Py_BUILD_CORE_MODULE
180202

181-
#define _PyInterpreterState_GetXIState(interp) (&(interp)->xi)
203+
int _Py_xi_global_state_init(_PyXI_global_state_t *);
204+
void _Py_xi_global_state_fini(_PyXI_global_state_t *);
205+
int _Py_xi_state_init(_PyXI_state_t *, PyInterpreterState *);
206+
void _Py_xi_state_fini(_PyXI_state_t *, PyInterpreterState *);
182207

183208

184209
/***************************/

Include/internal/pycore_crossinterp_data_registry.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,13 @@ typedef struct {
2727
_PyXIData_regitem_t *head;
2828
} _PyXIData_registry_t;
2929

30-
PyAPI_FUNC(int) _PyXIData_RegisterClass(PyTypeObject *, xidatafunc);
31-
PyAPI_FUNC(int) _PyXIData_UnregisterClass(PyTypeObject *);
30+
PyAPI_FUNC(int) _PyXIData_RegisterClass(
31+
_PyXIData_lookup_context_t *,
32+
PyTypeObject *,
33+
xidatafunc);
34+
PyAPI_FUNC(int) _PyXIData_UnregisterClass(
35+
_PyXIData_lookup_context_t *,
36+
PyTypeObject *);
3237

3338
struct _xid_lookup_state {
3439
// XXX Remove this field once we have a tp_* slot.

Modules/_interpchannelsmodule.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1758,6 +1758,11 @@ channel_send(_channels *channels, int64_t cid, PyObject *obj,
17581758
}
17591759
int64_t interpid = PyInterpreterState_GetID(interp);
17601760

1761+
_PyXIData_lookup_context_t ctx;
1762+
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
1763+
return -1;
1764+
}
1765+
17611766
// Look up the channel.
17621767
PyThread_type_lock mutex = NULL;
17631768
_channel_state *chan = NULL;
@@ -1779,7 +1784,7 @@ channel_send(_channels *channels, int64_t cid, PyObject *obj,
17791784
PyThread_release_lock(mutex);
17801785
return -1;
17811786
}
1782-
if (_PyObject_GetXIData(obj, data) != 0) {
1787+
if (_PyObject_GetXIData(&ctx, obj, data) != 0) {
17831788
PyThread_release_lock(mutex);
17841789
GLOBAL_FREE(data);
17851790
return -1;

Modules/_interpqueuesmodule.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,6 +1127,12 @@ queue_destroy(_queues *queues, int64_t qid)
11271127
static int
11281128
queue_put(_queues *queues, int64_t qid, PyObject *obj, int fmt, int unboundop)
11291129
{
1130+
PyInterpreterState *interp = PyInterpreterState_Get();
1131+
_PyXIData_lookup_context_t ctx;
1132+
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
1133+
return -1;
1134+
}
1135+
11301136
// Look up the queue.
11311137
_queue *queue = NULL;
11321138
int err = _queues_lookup(queues, qid, &queue);
@@ -1141,13 +1147,12 @@ queue_put(_queues *queues, int64_t qid, PyObject *obj, int fmt, int unboundop)
11411147
_queue_unmark_waiter(queue, queues->mutex);
11421148
return -1;
11431149
}
1144-
if (_PyObject_GetXIData(obj, data) != 0) {
1150+
if (_PyObject_GetXIData(&ctx, obj, data) != 0) {
11451151
_queue_unmark_waiter(queue, queues->mutex);
11461152
GLOBAL_FREE(data);
11471153
return -1;
11481154
}
1149-
assert(_PyXIData_INTERPID(data) == \
1150-
PyInterpreterState_GetID(PyInterpreterState_Get()));
1155+
assert(_PyXIData_INTERPID(data) == PyInterpreterState_GetID(interp));
11511156

11521157
// Add the data to the queue.
11531158
int64_t interpid = -1; // _queueitem_init() will set it.

Modules/_interpreters_common.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,24 @@
88
static int
99
ensure_xid_class(PyTypeObject *cls, xidatafunc getdata)
1010
{
11-
//assert(cls->tp_flags & Py_TPFLAGS_HEAPTYPE);
12-
return _PyXIData_RegisterClass(cls, getdata);
11+
PyInterpreterState *interp = PyInterpreterState_Get();
12+
_PyXIData_lookup_context_t ctx;
13+
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
14+
return -1;
15+
}
16+
return _PyXIData_RegisterClass(&ctx, cls, getdata);
1317
}
1418

1519
#ifdef REGISTERS_HEAP_TYPES
1620
static int
1721
clear_xid_class(PyTypeObject *cls)
1822
{
19-
return _PyXIData_UnregisterClass(cls);
23+
PyInterpreterState *interp = PyInterpreterState_Get();
24+
_PyXIData_lookup_context_t ctx;
25+
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
26+
return -1;
27+
}
28+
return _PyXIData_UnregisterClass(&ctx, cls);
2029
}
2130
#endif
2231

Modules/_interpretersmodule.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,7 +1186,13 @@ object_is_shareable(PyObject *self, PyObject *args, PyObject *kwds)
11861186
return NULL;
11871187
}
11881188

1189-
if (_PyObject_CheckXIData(obj) == 0) {
1189+
PyInterpreterState *interp = PyInterpreterState_Get();
1190+
_PyXIData_lookup_context_t ctx;
1191+
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
1192+
return NULL;
1193+
}
1194+
1195+
if (_PyObject_CheckXIData(&ctx, obj) == 0) {
11901196
Py_RETURN_TRUE;
11911197
}
11921198
PyErr_Clear();
@@ -1485,6 +1491,11 @@ module_exec(PyObject *mod)
14851491
PyInterpreterState *interp = PyInterpreterState_Get();
14861492
module_state *state = get_module_state(mod);
14871493

1494+
_PyXIData_lookup_context_t ctx;
1495+
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
1496+
return -1;
1497+
}
1498+
14881499
#define ADD_WHENCE(NAME) \
14891500
if (PyModule_AddIntConstant(mod, "WHENCE_" #NAME, \
14901501
_PyInterpreterState_WHENCE_##NAME) < 0) \
@@ -1506,9 +1517,7 @@ module_exec(PyObject *mod)
15061517
if (PyModule_AddType(mod, (PyTypeObject *)PyExc_InterpreterNotFoundError) < 0) {
15071518
goto error;
15081519
}
1509-
PyObject *PyExc_NotShareableError = \
1510-
_PyInterpreterState_GetXIState(interp)->exceptions.PyExc_NotShareableError;
1511-
if (PyModule_AddType(mod, (PyTypeObject *)PyExc_NotShareableError) < 0) {
1520+
if (PyModule_AddType(mod, (PyTypeObject *)ctx.PyExc_NotShareableError) < 0) {
15121521
goto error;
15131522
}
15141523

Modules/_testinternalcapi.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,12 @@ _xid_capsule_destructor(PyObject *capsule)
17971797
static PyObject *
17981798
get_crossinterp_data(PyObject *self, PyObject *args)
17991799
{
1800+
PyInterpreterState *interp = PyInterpreterState_Get();
1801+
_PyXIData_lookup_context_t ctx;
1802+
if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
1803+
return NULL;
1804+
}
1805+
18001806
PyObject *obj = NULL;
18011807
if (!PyArg_ParseTuple(args, "O:get_crossinterp_data", &obj)) {
18021808
return NULL;
@@ -1806,7 +1812,7 @@ get_crossinterp_data(PyObject *self, PyObject *args)
18061812
if (data == NULL) {
18071813
return NULL;
18081814
}
1809-
if (_PyObject_GetXIData(obj, data) != 0) {
1815+
if (_PyObject_GetXIData(&ctx, obj, data) != 0) {
18101816
_PyXIData_Free(data);
18111817
return NULL;
18121818
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy