micropython-samples/uasyncio_iostream/uasyncio/semaphore.py

42 wiersze
1.0 KiB
Python

# semaphore.py
import uasyncio
class Semaphore((uasyncio.Primitive)):
def __init__(self, value=1):
super().__init__()
self._count = value
async def __aenter__(self):
await self.acquire()
return self
async def __aexit__(self, exc_type, exc, tb):
self.release()
async def acquire(self):
if self._count == 0:
# Semaphore unavailable, put the calling Task on the waiting queue
self.save_current()
yield
self._count -= 1
def release(self):
self._count += 1
self.run_next() # Task(s) waiting on semaphore, schedule first Task
class BoundedSemaphore(Semaphore):
def __init__(self, value=1):
super().__init__(value)
self._initial_value = value
def release(self):
if self._count < self._initial_value:
super().release()
else:
raise ValueError('Semaphore released more than acquired')
uasyncio.Semaphore = Semaphore
uasyncio.BoundedSemaphore = BoundedSemaphore