os_trait/
notifier.rs

1use crate::{Duration, OsInterface, Timeout};
2
3/// This method should be able to call from task or ISR.
4/// The implementation should handle the different situations.
5pub trait NotifierInterface: Send + Clone {
6    fn notify(&self) -> bool;
7}
8
9pub trait NotifyWaiterInterface<OS: OsInterface>: Send {
10    /// Wait until notified or timeout occurs.
11    /// # Returns
12    ///   - `true` notified
13    ///   - `false` timeout occurred
14    fn wait(&self, timeout: &Duration<OS>) -> bool;
15
16    /// # Description
17    /// Wait for a notification, and call your function to check anything you want
18    /// when receiving a notification. You can control whether or not to continue
19    /// waiting for the next notification.
20    ///
21    /// # Parameters
22    /// - `timeout`: Total timeout.
23    /// - `f`: Your function. If it returns `Some(x)`, it will break out of the wait.
24    ///
25    /// # Returns
26    /// - `None`: It's timeout.
27    /// - `Some(x)`: The value returned by your function.
28    #[inline]
29    fn wait_with<U>(&self, timeout: &Duration<OS>, mut f: impl FnMut() -> Option<U>) -> Option<U> {
30        let mut wait_time = timeout.clone();
31        let mut t = Timeout::<OS>::from(timeout);
32        loop {
33            if let Some(rst) = f() {
34                return Some(rst);
35            }
36            if t.timeout() {
37                return None;
38            }
39
40            let left_time = t.time_left();
41            if left_time < wait_time {
42                wait_time = left_time;
43            }
44            self.wait(&wait_time);
45        }
46    }
47}