Skip to main content

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}