os_trait/
notifier.rs

1use crate::fugit::MicrosDurationU32;
2
3/// This method should be able to call from task or ISR.
4/// The implementation should handle the different situations.
5pub trait Notifier: Send + Sync {
6    fn notify(&self) -> bool;
7}
8
9pub trait NotifyWaiter: Send {
10    /// Wait until notified or timeout occurs.
11    /// # Returns
12    ///   - `true` notified
13    ///   - `false` timeout occurred
14    fn wait(&self, timeout: MicrosDurationU32) -> bool;
15
16    /// # Parameters
17    /// - `timeout`: Total timeout.
18    /// - `count`: How many times to split the total timeout.
19    ///   Your function will be called after each small timeout.
20    ///   It's useful when you want to check something while it's waiting.
21    ///   If you’re not sure, set it to `1`. Do **NOT** set it to `0`.
22    /// - `f`: Your function. If it returns `Some()`, it will break out of the wait.
23    ///
24    /// # Returns
25    /// - `None`: It's timeout.
26    /// - `Some(x)`: The value returned by your function.
27    #[inline]
28    fn wait_with<U>(
29        &self,
30        timeout: MicrosDurationU32,
31        count: u32,
32        mut f: impl FnMut() -> Option<U>,
33    ) -> Option<U> {
34        assert!(count > 0);
35        let t = MicrosDurationU32::from_ticks(timeout.ticks() / count);
36        let mut i = 0;
37        loop {
38            if let Some(rst) = f() {
39                return Some(rst);
40            }
41
42            i += 1;
43            if i > count {
44                return None;
45            }
46            self.wait(t);
47        }
48    }
49}