embassy_supervisor/data_deps/gated.rs
1use core::ops::Deref;
2
3use crate::{Coupling, Sig, TaskNode};
4
5#[allow(async_fn_in_trait)]
6/// A signal whose producer must be running and ready before a reader can use it.
7pub trait Gated {
8 /// Handle returned by [`open`](TaskNode::open) after the gate passes.
9 /// Counting gates return a guard; simple gates return `&'static Self`.
10 type Handle: Deref;
11
12 /// Admit a reader before [`ensure`](Self::ensure) runs, so the producer
13 /// sees an incoming reader and a cancelled `open` can roll back.
14 fn admit(&'static self) -> Self::Handle;
15
16 /// Ensure the producer of `entry` is serving from the perspective of `caller`.
17 async fn ensure(&'static self, caller: &'static TaskNode, entry: &'static Coupling);
18}
19
20impl TaskNode {
21 /// Open a gated signal: admit this node, wait for the producer, then
22 /// return the gate's handle. For [`Backed`](crate::Backed) this is an
23 /// [`Open`](crate::Open) guard; dropping it lets the producer retire.
24 pub async fn open<T: Gated + Sync + ?Sized>(&'static self, s: Sig<T>) -> T::Handle {
25 let handle = s.target.admit();
26 s.target.ensure(self, s.entry).await;
27 handle
28 }
29}