https://github.com/python/cpython/commit/8e0b36006c0b82e47e1cb5d367ec78532f21cee5
commit: 8e0b36006c0b82e47e1cb5d367ec78532f21cee5
branch: main
author: Kumar Aditya <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2025-01-24T21:12:56+05:30
summary:

gh-128002: use `_PyObject_SetMaybeWeakref` when creating tasks in asyncio 
(#128885)

files:
M Lib/test/test_asyncio/test_free_threading.py
M Modules/_asynciomodule.c

diff --git a/Lib/test/test_asyncio/test_free_threading.py 
b/Lib/test/test_asyncio/test_free_threading.py
index 05106a2c2fe3f6..c91719cb577c2f 100644
--- a/Lib/test/test_asyncio/test_free_threading.py
+++ b/Lib/test/test_asyncio/test_free_threading.py
@@ -1,4 +1,5 @@
 import asyncio
+import threading
 import unittest
 from threading import Thread
 from unittest import TestCase
@@ -58,6 +59,38 @@ def runner():
         with threading_helper.start_threads(threads):
             pass
 
+    def test_all_tasks_different_thread(self) -> None:
+        loop = None
+        started = threading.Event()
+
+        async def coro():
+            await asyncio.sleep(0.01)
+
+        lock = threading.Lock()
+        tasks = set()
+
+        async def main():
+            nonlocal tasks, loop
+            loop = asyncio.get_running_loop()
+            started.set()
+            for i in range(1000):
+                with lock:
+                    asyncio.create_task(coro())
+                    tasks = self.all_tasks(loop)
+
+        runner = threading.Thread(target=lambda: asyncio.run(main()))
+
+        def check():
+            started.wait()
+            with lock:
+                self.assertSetEqual(tasks & self.all_tasks(loop), tasks)
+
+        threads = [threading.Thread(target=check) for _ in range(10)]
+        threads.append(runner)
+
+        with threading_helper.start_threads(threads):
+            pass
+
     def test_run_coroutine_threadsafe(self) -> None:
         results = []
 
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index c821860d9e4f70..d5d49658555f1a 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -9,6 +9,7 @@
 #include "pycore_llist.h"         // struct llist_node
 #include "pycore_modsupport.h"    // _PyArg_CheckPositional()
 #include "pycore_moduleobject.h"  // _PyModule_GetState()
+#include "pycore_object.h"        // _PyObject_SetMaybeWeakref
 #include "pycore_pyerrors.h"      // _PyErr_ClearExcState()
 #include "pycore_pylifecycle.h"   // _Py_IsInterpreterFinalizing()
 #include "pycore_pystate.h"       // _PyThreadState_GET()
@@ -2466,6 +2467,11 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject 
*coro, PyObject *loop,
     if (task_call_step_soon(state, self, NULL)) {
         return -1;
     }
+#ifdef Py_GIL_DISABLED
+    // This is required so that _Py_TryIncref(self)
+    // works correctly in non-owning threads.
+    _PyObject_SetMaybeWeakref((PyObject *)self);
+#endif
     register_task(state, self);
     return 0;
 }

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to