mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-26 09:28:13 +00:00
feat(core): remove loop.chan
[no changelog]
This commit is contained in:
parent
48b9c8456f
commit
30be63a0b8
@ -334,104 +334,6 @@ class race(Syscall):
|
||||
raise
|
||||
|
||||
|
||||
class chan:
|
||||
"""
|
||||
Two-ended channel.
|
||||
The receiving end pauses until a value to be received is available. The sending end
|
||||
can choose to wait until the value is received, or it can publish the value without
|
||||
waiting.
|
||||
|
||||
Example:
|
||||
|
||||
>>> # in task #1:
|
||||
>>> signal = loop.chan()
|
||||
>>> while True:
|
||||
>>> result = await signal.take()
|
||||
>>> print("awaited result:", result)
|
||||
|
||||
>>> # in task #2:
|
||||
>>> signal.publish("Published without waiting")
|
||||
>>> print("publish completed")
|
||||
>>> await signal.put("Put with await")
|
||||
>>> print("put completed")
|
||||
|
||||
Example Output:
|
||||
|
||||
publish completed
|
||||
awaited result: Published without waiting
|
||||
awaited result: Put with await
|
||||
put completed
|
||||
"""
|
||||
|
||||
class Put(Syscall):
|
||||
def __init__(self, ch: "chan", value: Any) -> None:
|
||||
self.ch = ch
|
||||
self.value = value
|
||||
self.task: Task | None = None
|
||||
|
||||
def handle(self, task: Task) -> None:
|
||||
self.task = task
|
||||
self.ch._schedule_put(task, self.value)
|
||||
|
||||
class Take(Syscall):
|
||||
def __init__(self, ch: "chan") -> None:
|
||||
self.ch = ch
|
||||
self.task: Task | None = None
|
||||
|
||||
def handle(self, task: Task) -> None:
|
||||
self.task = task
|
||||
self.ch._schedule_take(task)
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.putters: list[tuple[Task | None, Any]] = []
|
||||
self.takers: list[Task] = []
|
||||
|
||||
def put(self, value: Any) -> Awaitable[None]: # type: ignore [awaitable-return-type]
|
||||
put = chan.Put(self, value)
|
||||
try:
|
||||
return (yield put) # type: ignore [awaitable-return-type]
|
||||
except: # noqa: E722
|
||||
entry = (put.task, value)
|
||||
if entry in self.putters:
|
||||
self.putters.remove(entry)
|
||||
raise
|
||||
|
||||
def take(self) -> Awaitable[Any]: # type: ignore [awaitable-return-type]
|
||||
take = chan.Take(self)
|
||||
try:
|
||||
return (yield take) # type: ignore [awaitable-return-type]
|
||||
except: # noqa: E722
|
||||
if take.task in self.takers:
|
||||
self.takers.remove(take.task)
|
||||
raise
|
||||
|
||||
def publish(self, value: Any) -> None:
|
||||
if self.takers:
|
||||
taker = self.takers.pop(0)
|
||||
schedule(taker, value)
|
||||
else:
|
||||
self.putters.append((None, value))
|
||||
|
||||
def _schedule_put(self, putter: Task, value: Any) -> bool:
|
||||
if self.takers:
|
||||
taker = self.takers.pop(0)
|
||||
schedule(taker, value)
|
||||
schedule(putter)
|
||||
return True
|
||||
else:
|
||||
self.putters.append((putter, value))
|
||||
return False
|
||||
|
||||
def _schedule_take(self, taker: Task) -> None:
|
||||
if self.putters:
|
||||
putter, value = self.putters.pop(0)
|
||||
schedule(taker, value)
|
||||
if putter is not None:
|
||||
schedule(putter)
|
||||
else:
|
||||
self.takers.append(taker)
|
||||
|
||||
|
||||
class spawn(Syscall):
|
||||
"""Spawn a task asynchronously and get an awaitable reference to it.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user