summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--extmod/uasyncio/__init__.py1
-rw-r--r--extmod/uasyncio/event.py31
2 files changed, 32 insertions, 0 deletions
diff --git a/extmod/uasyncio/__init__.py b/extmod/uasyncio/__init__.py
index 08f924cf29..fa64438f6b 100644
--- a/extmod/uasyncio/__init__.py
+++ b/extmod/uasyncio/__init__.py
@@ -10,6 +10,7 @@ _attrs = {
"wait_for_ms": "funcs",
"gather": "funcs",
"Event": "event",
+ "ThreadSafeFlag": "event",
"Lock": "lock",
"open_connection": "stream",
"start_server": "stream",
diff --git a/extmod/uasyncio/event.py b/extmod/uasyncio/event.py
index 31cb00e055..c28ad1fb31 100644
--- a/extmod/uasyncio/event.py
+++ b/extmod/uasyncio/event.py
@@ -14,6 +14,8 @@ class Event:
def set(self):
# 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():
core._task_queue.push_head(self.waiting.pop_head())
self.state = True
@@ -29,3 +31,32 @@ class Event:
core.cur_task.data = self.waiting
yield
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