diff --git a/asyncio/core.py b/asyncio/core.py index 33168e3..dcd4b24 100644 --- a/asyncio/core.py +++ b/asyncio/core.py @@ -69,7 +69,6 @@ def __next__(self): self.exc.__traceback__ = None raise self.exc - # Pause task execution for the given time (integer in milliseconds, uPy extension) # Use a SingletonGenerator to do it without allocating on the heap def sleep_ms(t, sgen=SingletonGenerator()): @@ -93,6 +92,34 @@ def sleep(t): return sleep_ms(int(t * 1000)) +################################################################################ +# "Never schedule" object" +# Don't re-schedule the object that awaits the _never singleton. +# For internal use only. Some constructs, like `await event.wait()`, +# work by NOT re-scheduling the task which calls wait(), but by +# having some other task schedule it later. +class _Never: + def __init__(self): + self.state = None + self.exc = StopIteration() + + def __iter__(self): + return self + + def __await__(self): + return self + + def __next__(self): + if self.state is not None: + self.state = None + return None + else: + self.exc.__traceback__ = None + raise self.exc + +_never = _Never() + + ################################################################################ # Queue and poller for stream IO diff --git a/asyncio/event.py b/asyncio/event.py index 3d02175..442c5bb 100644 --- a/asyncio/event.py +++ b/asyncio/event.py @@ -62,7 +62,8 @@ async def wait(self): self.waiting.push_head(core.cur_task) # Set calling task's data to the event's queue so it can be removed if needed core.cur_task.data = self.waiting - yield + core._never.state = False + await core._never return True diff --git a/asyncio/lock.py b/asyncio/lock.py index 5b4fe18..b5080a3 100644 --- a/asyncio/lock.py +++ b/asyncio/lock.py @@ -69,7 +69,8 @@ async def acquire(self): # Set calling task's data to the lock's queue so it can be removed if needed core.cur_task.data = self.waiting try: - yield + core._never.state = False + await core._never except core.CancelledError as er: if self.state == core.cur_task: # Cancelled while pending on resume, schedule next waiting Task