diff --git a/0003-Save-and-restore-the-tstate-cframe-as-part-of-the-gr.patch b/0003-Save-and-restore-the-tstate-cframe-as-part-of-the-gr.patch new file mode 100644 index 0000000000000000000000000000000000000000..151c3cd13fe47a61e087f7fbcdde17464e600155 --- /dev/null +++ b/0003-Save-and-restore-the-tstate-cframe-as-part-of-the-gr.patch @@ -0,0 +1,114 @@ +From 352b974447bb489cb2778e07c3832d0cc60e0e4a Mon Sep 17 00:00:00 2001 +From: Jason Madden +Date: Wed, 5 May 2021 11:13:03 -0500 +Subject: [PATCH] Save and restore the tstate->cframe as part of the greenlet + structure on 3.10. + +This fixes the crashes that the python.org interpreter was having in the test suite. + +This does not require a major version bump, even though the structure changed, because there hasn't been a 3.10 compatible release of greenlet yet. +--- + src/greenlet/greenlet.c | 20 +++++++++++++++++-- + src/greenlet/greenlet.h | 3 +++ + .../tests/test_extension_interface.py | 3 +++ + 3 files changed, 24 insertions(+), 2 deletions(-) + +diff --git a/src/greenlet/greenlet.c b/src/greenlet/greenlet.c +index eeece04..e299ed0 100644 +--- a/src/greenlet/greenlet.c ++++ b/src/greenlet/greenlet.c +@@ -100,10 +100,13 @@ extern PyTypeObject PyGreenlet_Type; + /* + Python 3.10 beta 1 changed tstate->use_tracing to a nested cframe member. + See https://github.com/python/cpython/pull/25276 ++We have to save and restore this as well. + */ + #define TSTATE_USE_TRACING(tstate) (tstate->cframe->use_tracing) ++#define GREENLET_USE_CFRAME 1 + #else + #define TSTATE_USE_TRACING(tstate) (tstate->use_tracing) ++#define GREENLET_USE_CFRAME 0 + #endif + + #ifndef Py_SET_REFCNT +@@ -514,6 +517,9 @@ g_switchstack(void) + current->exc_type = tstate->exc_type; + current->exc_value = tstate->exc_value; + current->exc_traceback = tstate->exc_traceback; ++#endif ++#if GREENLET_USE_CFRAME ++ current->cframe = tstate->cframe; + #endif + } + err = slp_switch(); +@@ -558,6 +564,10 @@ g_switchstack(void) + #endif + green_clear_exc(target); + ++#if GREENLET_USE_CFRAME ++ tstate->cframe = target->cframe; ++#endif ++ + assert(ts_origin == NULL); + Py_INCREF(target); + ts_current = target; +@@ -907,6 +917,9 @@ green_new(PyTypeObject* type, PyObject* args, PyObject* kwds) + } + Py_INCREF(ts_current); + ((PyGreenlet*)o)->parent = ts_current; ++#if GREENLET_USE_CFRAME ++ ((PyGreenlet*)o)->cframe = &PyThreadState_GET()->root_cframe; ++#endif + } + return o; + } +@@ -1611,8 +1624,9 @@ PyGreenlet_SetParent(PyGreenlet* g, PyGreenlet* nparent) + static PyGreenlet* + PyGreenlet_New(PyObject* run, PyGreenlet* parent) + { ++ /* XXX: Why doesn't this call green_new()? There's some duplicate ++ code. */ + PyGreenlet* g = NULL; +- + g = (PyGreenlet*)PyType_GenericAlloc(&PyGreenlet_Type, 0); + if (g == NULL) { + return NULL; +@@ -1635,7 +1649,9 @@ PyGreenlet_New(PyObject* run, PyGreenlet* parent) + return NULL; + } + } +- ++#if GREENLET_USE_CFRAME ++ g->cframe = &PyThreadState_GET()->root_cframe; ++#endif + return g; + } + +diff --git a/src/greenlet/greenlet.h b/src/greenlet/greenlet.h +index 1397782..830bef8 100644 +--- a/src/greenlet/greenlet.h ++++ b/src/greenlet/greenlet.h +@@ -38,6 +38,9 @@ typedef struct _greenlet { + #if PY_VERSION_HEX >= 0x030700A3 + PyObject* context; + #endif ++#if PY_VERSION_HEX >= 0x30A00B1 ++ CFrame* cframe; ++#endif + } PyGreenlet; + + #define PyGreenlet_Check(op) PyObject_TypeCheck(op, &PyGreenlet_Type) +diff --git a/src/greenlet/tests/test_extension_interface.py b/src/greenlet/tests/test_extension_interface.py +index bc87452..a92ea1f 100644 +--- a/src/greenlet/tests/test_extension_interface.py ++++ b/src/greenlet/tests/test_extension_interface.py +@@ -72,3 +72,6 @@ class CAPITests(unittest.TestCase): + str(seen[0]), + 'take that sucka!', + "message doesn't match") ++ ++if __name__ == '__main__': ++ unittest.main() +-- +2.39.0.windows.2 + diff --git a/python-greenlet.spec b/python-greenlet.spec index 4709ceb30e5764e16dba8b3c9957e693846e7762..d4547299f433e0b348abb77031fdb237f5e19c56 100644 --- a/python-greenlet.spec +++ b/python-greenlet.spec @@ -1,11 +1,12 @@ Name: python-greenlet Version: 1.1.2 -Release: 2 +Release: 3 Summary: lightweight coroutines for in-process concurrent programming License: Python-2.0 and MIT URL: https://github.com/python-greenlet/greenlet Source0: https://files.pythonhosted.org/packages/0c/10/754e21b5bea89d0e73f99d60c83754df7cc64db74f47d98ab187669ce341/greenlet-1.1.2.tar.gz Patch0001: 0001-Closes-305-Add-Python-3.11-support.patch +Patch0002: 0003-Save-and-restore-the-tstate-cframe-as-part-of-the-gr.patch %description The greenlet package is a spin-off of Stackless, a version of CPython that supports micro-threads called "tasklets". Tasklets run pseudo-concurrently @@ -60,6 +61,9 @@ that use python3-greenlet. %{_includedir}/python%{python3_version}*/greenlet/ %changelog +* Fri Dec 22 2023 zhangliangpengkun - 1.1.2-3 +- Save and restore the tstate->cframe as part of the greenlet structure on 3.10. + * Wed Oct 25 2023 zhangliangpengkun - 1.1.2-2 - Add Python 3.11 support