pythoncoder wrote: ↑Tue Apr 07, 2020 5:02 pm
Event.set() no longer accepts an optional data argument
...Note that the official Event is more efficient: mine relies on polling to achieve its ISR friendliness. If Event becomes ISR friendly I will make Message a subclass of Event to inherit its efficiency....
If I understand the code correctly, the Message class you have implemented only sets flags on itself.
The async wait method will loop until the flag becomes True. is this the polling you speak of?
Code: Select all
# micropython-samples/uasyncio_iostream/v3/primitives/message.py
class Message():
def __init__(self, delay_ms=0):
self.delay_ms = delay_ms
self.clear()
def clear(self):
self._flag = False
self._data = None
async def wait(self): # CPython comptaibility
while not self._flag:
await asyncio.sleep_ms(self.delay_ms)
def __await__(self):
while not self._flag:
await asyncio.sleep_ms(self.delay_ms)
__iter__ = __await__
def is_set(self):
return self._flag
def set(self, data=None):
self._flag = True
self._data = data
def value(self):
return self._data
At first glance the official Event class does not look much different.
The only difference I can see, which is likely to be of great significance, is that the wait method is no loop at all.
It simple pushes the current task on a queue and returns true.
Later on, when an event is set, this pops the queue, returning a value or starting a new coroutine.
for completion, here's the Event class I was looking at:
Code: Select all
# MicroPython uasyncio module
# MIT license; Copyright (c) 2019-2020 Damien P. George
from . import core
# Event class for primitive events that can be waited on, set, and cleared
class Event:
def __init__(self):
self.state = False # False=unset; True=set
self.waiting = core.TaskQueue() # Queue of Tasks waiting on completion of this event
def is_set(self):
return self.state
def set(self):
# Event becomes set, schedule any tasks waiting on it
while self.waiting.peek():
core._task_queue.push_head(self.waiting.pop_head())
self.state = True
def clear(self):
self.state = False
async def wait(self):
if not self.state:
# Event not set, put the calling task on the event's waiting queue
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
return True
Now, I know absolutely nothing about ISR's besides from what I read in 5 minutes looking at the docs... But you've peeked my interest.
What makes Event ISR unfriendly? As far as I can tell, the main loop gets interrupted only briefly and it will always wait for object creations to complete so no coro is left with any half updated object. What kind of use cases are ISR unfriendly?
regards,
Chris