https://github.com/python/cpython/commit/97248204a1cc10bd3a66ce857535d133f6bc86a1
commit: 97248204a1cc10bd3a66ce857535d133f6bc86a1
branch: main
author: Sam Gross <colesb...@gmail.com>
committer: colesbury <colesb...@gmail.com>
date: 2024-07-19T15:26:29-04:00
summary:

gh-121621: Disable asyncio freelist in free-threaded build (#122046)

The futureobj freelist isn't thread-safe. We intend to re-enable the
freelist in a thread-safe way for 3.14 (but not 3.13).

files:
M Modules/_asynciomodule.c

diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index 05ac09fe31c48d..372f19794be0dd 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -138,8 +138,10 @@ typedef struct {
     /* Counter for autogenerated Task names */
     uint64_t task_name_counter;
 
+#ifndef Py_GIL_DISABLED
     futureiterobject *fi_freelist;
     Py_ssize_t fi_freelist_len;
+#endif
 
     /* Linked-list of all tasks which are instances of asyncio.Task or 
subclasses
        of it. Third party tasks implementations which don't inherit from
@@ -1579,14 +1581,14 @@ FutureIter_dealloc(futureiterobject *it)
 
     assert(_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE));
 
-    PyObject *module = ((PyHeapTypeObject*)tp)->ht_module;
-    asyncio_state *state = NULL;
-
     PyObject_GC_UnTrack(it);
     tp->tp_clear((PyObject *)it);
 
+#ifndef Py_GIL_DISABLED
     // GH-115874: We can't use PyType_GetModuleByDef here as the type might 
have
     // already been cleared, which is also why we must check if ht_module != 
NULL.
+    PyObject *module = ((PyHeapTypeObject*)tp)->ht_module;
+    asyncio_state *state = NULL;
     if (module && _PyModule_GetDef(module) == &_asynciomodule) {
         state = get_asyncio_state(module);
     }
@@ -1597,7 +1599,9 @@ FutureIter_dealloc(futureiterobject *it)
         it->future = (FutureObj*) state->fi_freelist;
         state->fi_freelist = it;
     }
-    else {
+    else
+#endif
+    {
         PyObject_GC_Del(it);
         Py_DECREF(tp);
     }
@@ -1801,6 +1805,7 @@ future_new_iter(PyObject *fut)
     asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut);
     ENSURE_FUTURE_ALIVE(state, fut)
 
+#ifndef Py_GIL_DISABLED
     if (state->fi_freelist_len) {
         state->fi_freelist_len--;
         it = state->fi_freelist;
@@ -1808,7 +1813,9 @@ future_new_iter(PyObject *fut)
         it->future = NULL;
         _Py_NewReference((PyObject*) it);
     }
-    else {
+    else
+#endif
+    {
         it = PyObject_GC_New(futureiterobject, state->FutureIterType);
         if (it == NULL) {
             return NULL;
@@ -3679,6 +3686,7 @@ _asyncio_all_tasks_impl(PyObject *module, PyObject *loop)
 static void
 module_free_freelists(asyncio_state *state)
 {
+#ifndef Py_GIL_DISABLED
     PyObject *next;
     PyObject *current;
 
@@ -3693,6 +3701,7 @@ module_free_freelists(asyncio_state *state)
     }
     assert(state->fi_freelist_len == 0);
     state->fi_freelist = NULL;
+#endif
 }
 
 static int
@@ -3723,6 +3732,7 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
 
     Py_VISIT(state->context_kwname);
 
+#ifndef Py_GIL_DISABLED
     // Visit freelist.
     PyObject *next = (PyObject*) state->fi_freelist;
     while (next != NULL) {
@@ -3730,6 +3740,8 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
         Py_VISIT(current);
         next = (PyObject*) ((futureiterobject*) current)->future;
     }
+#endif
+
     return 0;
 }
 

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to