[Python-checkins] GH-103092: port `_asyncio` freelist to module state (#104196)

kumaraditya303 webhook-mailer at python.org
Fri May 5 07:13:05 EDT 2023


https://github.com/python/cpython/commit/2318bedb3645d2dfb56944553f01d6c434904c4b
commit: 2318bedb3645d2dfb56944553f01d6c434904c4b
branch: main
author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com>
committer: kumaraditya303 <59607654+kumaraditya303 at users.noreply.github.com>
date: 2023-05-05T16:42:58+05:30
summary:

GH-103092: port `_asyncio` freelist to module state (#104196)

files:
M Modules/_asynciomodule.c

diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index 8b1a29b6d33e..fef34d655238 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -18,6 +18,10 @@ module _asyncio
 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fd17862aa989c69]*/
 
 
+#define FI_FREELIST_MAXLEN 255
+
+typedef struct futureiterobject futureiterobject;
+
 /* State of the _asyncio module */
 typedef struct {
     PyTypeObject *FutureIterType;
@@ -67,6 +71,9 @@ typedef struct {
 
     /* Counter for autogenerated Task names */
     uint64_t task_name_counter;
+
+    futureiterobject *fi_freelist;
+    Py_ssize_t fi_freelist_len;
 } asyncio_state;
 
 static inline asyncio_state *
@@ -1574,28 +1581,24 @@ FutureObj_dealloc(PyObject *self)
 
 /*********************** Future Iterator **************************/
 
-typedef struct {
+typedef struct futureiterobject {
     PyObject_HEAD
     FutureObj *future;
 } futureiterobject;
 
 
-#define FI_FREELIST_MAXLEN 255
-static futureiterobject *fi_freelist = NULL;
-static Py_ssize_t fi_freelist_len = 0;
-
-
 static void
 FutureIter_dealloc(futureiterobject *it)
 {
     PyTypeObject *tp = Py_TYPE(it);
+    asyncio_state *state = get_asyncio_state_by_def((PyObject *)it);
     PyObject_GC_UnTrack(it);
     tp->tp_clear((PyObject *)it);
 
-    if (fi_freelist_len < FI_FREELIST_MAXLEN) {
-        fi_freelist_len++;
-        it->future = (FutureObj*) fi_freelist;
-        fi_freelist = it;
+    if (state->fi_freelist_len < FI_FREELIST_MAXLEN) {
+        state->fi_freelist_len++;
+        it->future = (FutureObj*) state->fi_freelist;
+        state->fi_freelist = it;
     }
     else {
         PyObject_GC_Del(it);
@@ -1799,17 +1802,12 @@ future_new_iter(PyObject *fut)
     futureiterobject *it;
 
     asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut);
-    if (!Future_Check(state, fut)) {
-        PyErr_BadInternalCall();
-        return NULL;
-    }
-
     ENSURE_FUTURE_ALIVE(state, fut)
 
-    if (fi_freelist_len) {
-        fi_freelist_len--;
-        it = fi_freelist;
-        fi_freelist = (futureiterobject*) it->future;
+    if (state->fi_freelist_len) {
+        state->fi_freelist_len--;
+        it = state->fi_freelist;
+        state->fi_freelist = (futureiterobject*) it->future;
         it->future = NULL;
         _Py_NewReference((PyObject*) it);
     }
@@ -3556,22 +3554,22 @@ _asyncio_current_task_impl(PyObject *module, PyObject *loop)
 
 
 static void
-module_free_freelists(void)
+module_free_freelists(asyncio_state *state)
 {
     PyObject *next;
     PyObject *current;
 
-    next = (PyObject*) fi_freelist;
+    next = (PyObject*) state->fi_freelist;
     while (next != NULL) {
-        assert(fi_freelist_len > 0);
-        fi_freelist_len--;
+        assert(state->fi_freelist_len > 0);
+        state->fi_freelist_len--;
 
         current = next;
         next = (PyObject*) ((futureiterobject*) current)->future;
         PyObject_GC_Del(current);
     }
-    assert(fi_freelist_len == 0);
-    fi_freelist = NULL;
+    assert(state->fi_freelist_len == 0);
+    state->fi_freelist = NULL;
 }
 
 static int
@@ -3603,7 +3601,7 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
     Py_VISIT(state->context_kwname);
 
     // Visit freelist.
-    PyObject *next = (PyObject*) fi_freelist;
+    PyObject *next = (PyObject*) state->fi_freelist;
     while (next != NULL) {
         PyObject *current = next;
         Py_VISIT(current);
@@ -3640,7 +3638,7 @@ module_clear(PyObject *mod)
 
     Py_CLEAR(state->context_kwname);
 
-    module_free_freelists();
+    module_free_freelists(state);
 
     return 0;
 }



More information about the Python-checkins mailing list