-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
uasyncio: make uasyncio.Event() safe to call from an interrupt v2 (RFC, WIP) #6106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
uasyncio: make uasyncio.Event() safe to call from an interrupt v2 (RFC, WIP) #6106
Conversation
This is how CPython does it, using a special "self socket".
So it can be set from a scheduled callback (but not a hard IRQ). TODO: work out if it can be set from another thread, probably only with the GIL enabled.
This looks nicer than V1! Can you go further? In the stm32 port there's all that notifier stream object code when all that's really needed is a boolean flag... Why can't poll_poll_internal just check the flag in https://github.com/micropython/micropython/blob/master/extmod/moduselect.c#L250-L256 and return empty sets or EINTR if the flag is set? For the unix port, instead of the socketpair, have you looked at ppoll (or pselect), it seems to be designed exactly to solve the race condition you had with simply setting a flag in the signal handler. Caveat: I have not looked at the detail of how one has to use signal masks nor at how this works in a multithreaded context. I continue to find it awful that the WFI/sleep is buried in that MICROPY_EVENT_POLL_HOOK macro called in the bowels of poll, maybe that's unavoidable at the moment. |
Yeah, I realised that after I posted this PR. Would be even simpler to not even have a notifier object at all and instead have
Yes, good idea, that may work! Again though, this makes poll diverge even more from CPython. I'm actually working on a more drastic change that makes everything event/callback based and O(1) on bare-metal (eg lwip sockets call back into the polling loop to indicate they are readable/writable). And as part of this I'm making a separate |
Make countio object long-lived
This is a slight variation on #6056, making
uasyncio.Event().set()
safe to call from a soft-scheduled callback (withmicropython.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):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 callEvent.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.