@@ -1368,6 +1368,80 @@ def matches_awaited_by_pattern(task):
13681368 finally :
13691369 _cleanup_sockets (client_socket , server_socket )
13701370
1371+ @skip_if_not_supported
1372+ @unittest .skipIf (
1373+ sys .platform == "linux" and not PROCESS_VM_READV_SUPPORTED ,
1374+ "Test only runs on Linux with process_vm_readv support" ,
1375+ )
1376+ def test_async_global_awaited_by_from_non_main_thread (self ):
1377+ port = find_unused_port ()
1378+ script = textwrap .dedent (
1379+ f"""\
1380+ import asyncio
1381+ import socket
1382+ import threading
1383+ import time
1384+
1385+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1386+ sock.connect(('localhost', { port } ))
1387+
1388+ async def worker_main():
1389+ task = asyncio.create_task(
1390+ asyncio.sleep(10_000),
1391+ name="worker task",
1392+ )
1393+ await asyncio.sleep(0)
1394+ sock.sendall(f"ready:{{threading.get_native_id()}}\\ n".encode())
1395+ await task
1396+
1397+ def run_worker_loop():
1398+ asyncio.run(worker_main())
1399+
1400+ threading.Thread(
1401+ target=run_worker_loop,
1402+ name="async-worker",
1403+ daemon=True,
1404+ ).start()
1405+ time.sleep(10_000)
1406+ """
1407+ )
1408+
1409+ with os_helper .temp_dir () as work_dir :
1410+ script_dir = os .path .join (work_dir , "script_pkg" )
1411+ os .mkdir (script_dir )
1412+
1413+ server_socket = _create_server_socket (port )
1414+ script_name = _make_test_script (script_dir , "script" , script )
1415+ client_socket = None
1416+
1417+ try :
1418+ with _managed_subprocess ([sys .executable , script_name ]) as p :
1419+ client_socket , _ = server_socket .accept ()
1420+ server_socket .close ()
1421+ server_socket = None
1422+
1423+ response = _wait_for_signal (client_socket , b"ready:" )
1424+ worker_thread_id = int (
1425+ response .split (b"ready:" , 1 )[1 ].splitlines ()[0 ]
1426+ )
1427+
1428+ for _ in busy_retry (SHORT_TIMEOUT ):
1429+ all_awaited_by = get_all_awaited_by (p .pid )
1430+ if any (
1431+ task .task_name == "worker task"
1432+ for info in all_awaited_by
1433+ if info .thread_id == worker_thread_id
1434+ for task in info .awaited_by
1435+ ):
1436+ break
1437+ else :
1438+ self .fail (
1439+ "get_all_awaited_by() did not report "
1440+ "the asyncio task from the non-main thread"
1441+ )
1442+ finally :
1443+ _cleanup_sockets (client_socket , server_socket )
1444+
13711445 @skip_if_not_supported
13721446 @unittest .skipIf (
13731447 sys .platform == "linux" and not PROCESS_VM_READV_SUPPORTED ,
0 commit comments