extmod/uasyncio: Add ThreadSafeFlag.
This is a MicroPython-extension that allows for code running in IRQ (hard or soft) or scheduler context to sequence asyncio code. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This commit is contained in:
parent
4c54012373
commit
5e96e89999
@ -10,6 +10,7 @@ _attrs = {
|
|||||||
"wait_for_ms": "funcs",
|
"wait_for_ms": "funcs",
|
||||||
"gather": "funcs",
|
"gather": "funcs",
|
||||||
"Event": "event",
|
"Event": "event",
|
||||||
|
"ThreadSafeFlag": "event",
|
||||||
"Lock": "lock",
|
"Lock": "lock",
|
||||||
"open_connection": "stream",
|
"open_connection": "stream",
|
||||||
"start_server": "stream",
|
"start_server": "stream",
|
||||||
|
@ -14,6 +14,8 @@ class Event:
|
|||||||
|
|
||||||
def set(self):
|
def set(self):
|
||||||
# Event becomes set, schedule any tasks waiting on it
|
# Event becomes set, schedule any tasks waiting on it
|
||||||
|
# Note: This must not be called from anything except the thread running
|
||||||
|
# the asyncio loop (i.e. neither hard or soft IRQ, or a different thread).
|
||||||
while self.waiting.peek():
|
while self.waiting.peek():
|
||||||
core._task_queue.push_head(self.waiting.pop_head())
|
core._task_queue.push_head(self.waiting.pop_head())
|
||||||
self.state = True
|
self.state = True
|
||||||
@ -29,3 +31,32 @@ class Event:
|
|||||||
core.cur_task.data = self.waiting
|
core.cur_task.data = self.waiting
|
||||||
yield
|
yield
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
# MicroPython-extension: This can be set from outside the asyncio event loop,
|
||||||
|
# such as other threads, IRQs or scheduler context. Implementation is a stream
|
||||||
|
# that asyncio will poll until a flag is set.
|
||||||
|
# Note: Unlike Event, this is self-clearing.
|
||||||
|
try:
|
||||||
|
import uio
|
||||||
|
|
||||||
|
class ThreadSafeFlag(uio.IOBase):
|
||||||
|
def __init__(self):
|
||||||
|
self._flag = 0
|
||||||
|
|
||||||
|
def ioctl(self, req, flags):
|
||||||
|
if req == 3: # MP_STREAM_POLL
|
||||||
|
return self._flag * flags
|
||||||
|
return None
|
||||||
|
|
||||||
|
def set(self):
|
||||||
|
self._flag = 1
|
||||||
|
|
||||||
|
async def wait(self):
|
||||||
|
if not self._flag:
|
||||||
|
yield core._io_queue.queue_read(self)
|
||||||
|
self._flag = 0
|
||||||
|
|
||||||
|
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
Loading…
Reference in New Issue
Block a user