Skip to content

Commit d9b9d07

Browse files
CopilotXmader
andauthored
Apply remaining changes
Co-authored-by: Xmader <16057139+Xmader@users.noreply.github.com>
1 parent 0351c7b commit d9b9d07

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

‎src/PyEventLoop.cc‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,26 @@ PyEventLoop PyEventLoop::_loopNotFound() {
142142
PyEventLoop PyEventLoop::_getLoopOnThread(PyThreadState *tstate) {
143143
// Modified from Python 3.9 `get_running_loop` https://github.com/python/cpython/blob/7cb3a44/Modules/_asynciomodule.c#L241-L278
144144

145+
// For the current thread, ask asyncio itself instead of reading CPython's private thread-state layout,
146+
// which differs between patch releases (e.g. 3.14.3 vs 3.14.4).
147+
if (tstate == PyThreadState_Get()) {
148+
PyObject *asyncio = PyImport_ImportModule("asyncio");
149+
if (asyncio == NULL) {
150+
return _loopNotFound();
151+
}
152+
PyObject *loop = PyObject_CallMethod(asyncio, "_get_running_loop", NULL);
153+
Py_DECREF(asyncio);
154+
if (loop == NULL) {
155+
PyErr_Clear();
156+
return _loopNotFound();
157+
}
158+
if (loop == Py_None) {
159+
Py_DECREF(loop);
160+
return _loopNotFound();
161+
}
162+
return PyEventLoop(loop); // takes the new reference
163+
}
164+
145165
PyObject *ts_dict;
146166
#if PY_VERSION_HEX >= 0x030d0000 // Python version is greater than 3.13
147167
// The private `_PyThreadState_GetDict(tstate)` API gets removed in Python 3.13.
@@ -204,6 +224,14 @@ PyEventLoop PyEventLoop::_getLoopOnThread(PyThreadState *tstate) {
204224
// (we only need the first few fields of `_PyThreadStateImpl`)
205225
};
206226

227+
#if PY_VERSION_HEX >= 0x030e0000 && PY_VERSION_HEX < 0x030f0000
228+
// Python 3.14.4 added a pointer field to the public `PyThreadState`, shifting the offsets of the private fields.
229+
// Refuse to read another thread's state when the runtime and build-time layouts differ.
230+
if ((PY_VERSION_HEX >= 0x030e0400) != (Py_Version >= 0x030e0400)) {
231+
return _loopNotFound();
232+
}
233+
#endif
234+
207235
// Modified from https://github.com/python/cpython/blob/v3.13.0rc1/Modules/_asynciomodule.c#L3205-L3210
208236
PyObject *loop = ((PyThreadStateHolder *)tstate)->asyncio_running_loop;
209237
if (loop == NULL) {

0 commit comments

Comments
 (0)