Mercurial > code > home > repos > light9
diff blender/asyncio_thread.py @ 2454:405abed9a45c
fix up asyncio-in-bg-thread sorcery
author | drewp@bigasterisk.com |
---|---|
date | Mon, 19 May 2025 21:25:32 -0700 |
parents | b23afde50bc2 |
children |
line wrap: on
line diff
--- a/blender/asyncio_thread.py Sun May 18 20:08:35 2025 -0700 +++ b/blender/asyncio_thread.py Mon May 19 21:25:32 2025 -0700 @@ -1,16 +1,49 @@ import asyncio -from threading import Thread +import sys +from threading import Thread, get_ident +import time from typing import Coroutine +def log(msg): + try: + rl = hex(id(asyncio.get_running_loop())) + except RuntimeError: + rl = '(no loop ----)' + sys.stderr.write(f"thread={hex(get_ident())} loop={rl} {msg}\n") + + def startLoopInThread(task: Coroutine) -> asyncio.AbstractEventLoop: + """ + run a new event loop in a background thread. `task` is run in the new loop. + Caller should use this (from fg thread) to run further tasks: + asyncio.run_coroutine_threadsafe(task, returned_loop) - def start_background_loop(loop: asyncio.AbstractEventLoop) -> None: - asyncio.set_event_loop(loop) - loop.run_forever() + """ + log('🚋4 startLoopInThread enter ') + loops = [] + + def start_background_loop() -> None: + + async def forever(): + log('🚋6 log_loop') + loops.append(asyncio.get_running_loop()) + while True: + await asyncio.sleep(100) - loop = asyncio.new_event_loop() - t = Thread(target=start_background_loop, args=(loop,), daemon=True) + log('🚋5 make asyncio loop') + asyncio.run(forever()) + log('🚋19 start_background_loop done') + + t = Thread(target=start_background_loop, daemon=True) t.start() + while not loops: + time.sleep(.1) + loop = loops[0] + log('🚋7 loop has started in thread') + asyncio.run_coroutine_threadsafe(task, loop) + log('🚋8 started task') + + log('🚋9 startLoopInThread exit') return loop