extmod/uasyncio Event.set() not safe in ISR
If you call Event.set() in an ISR, you could end up losing all tasks that were awaiting the event (if the ISR is executed while uasyncio is sorting tasks on the queue e.g.).
I made a testscript a while ago to demonstrate this: https://gist.github.com/kevinkk525/5b89395604da3df3be7a015abcba04fa
uasyncio: make uasyncio.Event() safe to call from an interrupt v2 (RFC, WIP)
This is a slight variation on #6056, making uasyncio.Event().set() safe to call from a soft-scheduled callback (with micropython.schedule()).
This version does not introduce socket.socketpair() for the signalling, but rather hides this in the poll object as a more general "notifier" object. So you can now do this (independent to asyncio):
import uselect
poll = uselect.poll()
# pass None to register a special notifier entity; returns the notifier
# on unix the notifier is a socketpair, but it could be anything on other ports
notifier = poll.register(None, uselect.POLLIN)
def callback():
# set the notifier, will be irq/signal/thread safe
# this will wake any poll.poll() sleeps
notifier.set()
# sleep until an event
for ev, s in poll.poll():
if s is notifier:
# got woken by the notifier, clear it
s.clear()
This abstracts out a lot of the detail of poll and wake-up behaviour and should allow a bare-metal port more flexibility in implementing the notifier (eg with a semaphore).
Apart from the addition of micropython.scheduler_lock()/micropython.scheduler_unlock(), the only public facing API behaviour that is added here is the ability to call Event.set() from a scheduled callback. This would hopefully allow room for the underlying poll implementation to be completely changed (eg made more efficient) without the user noticing.