kopia lustrzana https://github.com/peterhinch/micropython-samples
61 wiersze
1.6 KiB
Python
61 wiersze
1.6 KiB
Python
import uasyncio
|
|
import uasyncio.lock
|
|
import uasyncio.event
|
|
|
|
class Condition:
|
|
def __init__(self, lock=None):
|
|
self.lock = uasyncio.Lock() if lock is None else lock
|
|
self.events = []
|
|
|
|
async def acquire(self):
|
|
await self.lock.acquire()
|
|
|
|
# enable this syntax:
|
|
# with await condition [as cond]:
|
|
#def __iter__(self):
|
|
#await self.lock.acquire()
|
|
#return self
|
|
|
|
async def __aenter__(self):
|
|
await self.lock.acquire()
|
|
return self
|
|
|
|
async def __aexit__(self, *_):
|
|
self.lock.release()
|
|
|
|
def locked(self):
|
|
return self.lock.locked()
|
|
|
|
def release(self):
|
|
self.lock.release() # Will raise RuntimeError if not locked
|
|
|
|
def notify(self, n=1): # Caller controls lock
|
|
if not self.lock.locked():
|
|
raise RuntimeError('Condition notify with lock not acquired.')
|
|
for _ in range(min(n, len(self.events))):
|
|
ev = self.events.pop()
|
|
ev.set()
|
|
|
|
def notify_all(self):
|
|
self.notify(len(self.events))
|
|
|
|
async def wait(self):
|
|
if not self.lock.locked():
|
|
raise RuntimeError('Condition wait with lock not acquired.')
|
|
ev = uasyncio.Event()
|
|
self.events.append(ev)
|
|
self.lock.release()
|
|
await ev.wait()
|
|
await self.lock.acquire()
|
|
assert ev not in self.events, 'condition wait assertion fail'
|
|
return True # CPython compatibility
|
|
|
|
async def wait_for(self, predicate):
|
|
result = predicate()
|
|
while not result:
|
|
await self.wait()
|
|
result = predicate()
|
|
return result
|
|
|
|
uasyncio.Condition = Condition
|