diff --git a/extmod/asyncio/core.py b/extmod/asyncio/core.py index 8aad234514b0c..fa45de3a50d21 100644 --- a/extmod/asyncio/core.py +++ b/extmod/asyncio/core.py @@ -3,6 +3,7 @@ from time import ticks_ms as ticks, ticks_diff, ticks_add import sys, select +from select import POLLIN, POLLOUT # Import TaskQueue and Task, preferring built-in C code over Python code try: @@ -54,7 +55,8 @@ def __next__(self): # Use a SingletonGenerator to do it without allocating on the heap def sleep_ms(t, sgen=SingletonGenerator()): assert sgen.state is None - sgen.state = ticks_add(ticks(), max(0, t)) + now = ticks() + sgen.state = ticks_add(now, t) if t > 0 else now return sgen @@ -66,6 +68,8 @@ def sleep(t): ################################################################################ # Queue and poller for stream IO +nPOLLIN = ~POLLIN +nPOLLOUT = ~POLLOUT class IOQueue: def __init__(self): @@ -77,13 +81,13 @@ def _enqueue(self, s, idx): entry = [None, None, s] entry[idx] = cur_task self.map[id(s)] = entry - self.poller.register(s, select.POLLIN if idx == 0 else select.POLLOUT) + self.poller.register(s, POLLIN if idx == 0 else POLLOUT) else: sm = self.map[id(s)] assert sm[idx] is None assert sm[1 - idx] is not None sm[idx] = cur_task - self.poller.modify(s, select.POLLIN | select.POLLOUT) + self.poller.modify(s, POLLIN | POLLOUT) # Link task to this IOQueue so it can be removed if needed cur_task.data = self @@ -114,20 +118,20 @@ def wait_io_event(self, dt): for s, ev in self.poller.ipoll(dt): sm = self.map[id(s)] # print('poll', s, sm, ev) - if ev & ~select.POLLOUT and sm[0] is not None: + if ev & nPOLLOUT and sm[0] is not None: # POLLIN or error _task_queue.push(sm[0]) sm[0] = None - if ev & ~select.POLLIN and sm[1] is not None: + if ev & nPOLLIN and sm[1] is not None: # POLLOUT or error _task_queue.push(sm[1]) sm[1] = None if sm[0] is None and sm[1] is None: self._dequeue(s) elif sm[0] is None: - self.poller.modify(s, select.POLLOUT) + self.poller.modify(s, POLLOUT) else: - self.poller.modify(s, select.POLLIN) + self.poller.modify(s, POLLIN) ################################################################################ @@ -153,24 +157,29 @@ def run_until_complete(main_task=None): global cur_task excs_all = (CancelledError, Exception) # To prevent heap allocation in loop excs_stop = (CancelledError, StopIteration) # To prevent heap allocation in loop + queue_peek = _task_queue.peek + queue_pop = _task_queue.pop + wait_io_event = _io_queue.wait_io_event while True: # Wait until the head of _task_queue is ready to run dt = 1 - while dt > 0: + while dt: dt = -1 - t = _task_queue.peek() + t = queue_peek() if t: # A task waiting on _task_queue; "ph_key" is time to schedule task at - dt = max(0, ticks_diff(t.ph_key, ticks())) + dt = ticks_diff(t.ph_key, ticks()) + if dt < 0: + dt = 0 elif not _io_queue.map: # No tasks can be woken so finished running cur_task = None return # print('(poll {})'.format(dt), len(_io_queue.map)) - _io_queue.wait_io_event(dt) + wait_io_event(dt) # Get next task to run and continue it - t = _task_queue.pop() + t = queue_pop() cur_task = t try: # Continue running the coroutine, it's responsible for rescheduling itself pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy