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 aa9c83ab967ef01e65523377edc5429a4aa51350..6eacc420963698e7bdcdd97789d3386b8be4a8e4 100644 --- a/python-greenlet.spec +++ b/python-greenlet.spec @@ -1,6 +1,6 @@ Name: python-greenlet Version: 1.0.0 -Release: 3 +Release: 4 Summary: lightweight coroutines for in-process concurrent programming License: Python-2.0 and MIT URL: https://github.com/python-greenlet/greenlet @@ -8,6 +8,7 @@ Source0: https://files.pythonhosted.org/packages/92/be/878cc5314fa5aadce Patch0: 0001-add-loongarch64-architecture-support.patch Patch1: 0002-Add-support-for-Python-3.10.patch +Patch2: 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 @@ -45,6 +46,7 @@ that use python3-greenlet. %ifarch loongarch64 %patch0 -p1 %patch1 -p1 +%patch2 -p1 %endif %build @@ -67,6 +69,9 @@ that use python3-greenlet. %{_includedir}/python%{python3_version}*/greenlet/ %changelog +* Fri Dec 22 2023 zhangliangpengkun - 1.0.0-4 +- Save and restore the tstate->cframe as part of the greenlet structure on 3.10 + * Wed Oct 25 2023 zhangliangpengkun - 1.0.0-3 - Add support for Python 3.10