extmod/uasyncio: Implement Loop.stop() to stop the event loop.

This commit is contained in:
Damien George 2020-03-30 14:58:13 +11:00
parent 711dd392d3
commit b389bc0afa
4 changed files with 74 additions and 2 deletions

View File

@ -251,13 +251,17 @@ Event Loop
.. method:: Loop.run_forever()
Run the event loop forever.
Run the event loop until `stop()` is called.
.. method:: Loop.run_until_complete(awaitable)
Run the given *awaitable* until it completes. If *awaitable* is not a task
then it will be promoted to one.
.. method:: Loop.stop()
Stop the event loop.
.. method:: Loop.close()
Close the event loop.

View File

@ -214,17 +214,33 @@ def run(coro):
# Event loop wrapper
async def _stopper():
pass
_stop_task = None
class Loop:
def create_task(coro):
return create_task(coro)
def run_forever():
run_until_complete()
global _stop_task
_stop_task = Task(_stopper(), globals())
run_until_complete(_stop_task)
# TODO should keep running until .stop() is called, even if there're no tasks left
def run_until_complete(aw):
return run_until_complete(_promote_to_task(aw))
def stop():
global _stop_task
if _stop_task is not None:
_task_queue.push_head(_stop_task)
# If stop() is called again, do nothing
_stop_task = None
def close():
pass

View File

@ -0,0 +1,45 @@
# Test Loop.stop() to stop the event loop
try:
import uasyncio as asyncio
except ImportError:
try:
import asyncio
except ImportError:
print("SKIP")
raise SystemExit
async def task():
print("task")
async def main():
print("start")
# Stop the loop after next yield
loop.stop()
# Check that calling stop() again doesn't do/break anything
loop.stop()
# This await should stop
print("sleep")
await asyncio.sleep(0)
# Schedule stop, then create a new task, then yield
loop.stop()
asyncio.create_task(task())
await asyncio.sleep(0)
# Final stop
print("end")
loop.stop()
loop = asyncio.get_event_loop()
loop.create_task(main())
for i in range(3):
print("run", i)
loop.run_forever()

View File

@ -0,0 +1,7 @@
run 0
start
sleep
run 1
run 2
task
end