Skip to main content

qubit_lock/monitor/
std_monitor.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 *    SPDX-License-Identifier: Apache-2.0
6 *
7 *    Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10//! # StdMonitor
11//!
12//! Provides a synchronous monitor built from a mutex and a condition variable.
13//! A monitor protects one shared state value and binds that state to the
14//! condition variable used to wait for changes. This is the same low-level
15//! mechanism as using [`std::sync::Mutex`] and [`std::sync::Condvar`] directly,
16//! but packaged so callers do not have to keep a mutex and its matching
17//! condition variable as separate fields.
18//!
19//! The high-level APIs ([`StdMonitor::read`], [`StdMonitor::write`],
20//! [`StdMonitor::wait_while`], and [`StdMonitor::wait_until`]) are intended for
21//! short critical sections and simple guarded-suspension flows. The lower-level
22//! [`StdMonitor::lock`] API returns a [`StdMonitorGuard`], which supports
23//! [`StdMonitorGuard::wait`] and [`StdMonitorGuard::wait_timeout`] for more complex
24//! state machines such as thread pools.
25//!
26
27use std::{
28    sync::{
29        Condvar,
30        Mutex,
31    },
32    time::{
33        Duration,
34        Instant,
35    },
36};
37
38use super::std_monitor_guard::StdMonitorGuard;
39use super::{
40    ConditionWaiter,
41    NotificationWaiter,
42    Notifier,
43    TimeoutConditionWaiter,
44    TimeoutNotificationWaiter,
45    wait_timeout_result::WaitTimeoutResult,
46    wait_timeout_status::WaitTimeoutStatus,
47};
48
49/// Shared state protected by a mutex and a condition variable.
50///
51/// `StdMonitor` is useful when callers need more than a short critical section.
52/// It models the classic monitor object pattern: one mutex protects the state,
53/// and one condition variable lets threads wait until that state changes. This
54/// is the same relationship used by `std::sync::Mutex` and
55/// `std::sync::Condvar`, but represented as one object so the condition
56/// variable is not accidentally used with unrelated state.
57///
58/// `StdMonitor` deliberately has two levels of API:
59///
60/// * `read` and `write` acquire the mutex, run a closure, and release it.
61/// * `wait_while`, `wait_until`, and their timeout variants implement common
62///   predicate-based waits.
63/// * `lock` returns a [`StdMonitorGuard`] for callers that need to write their own
64///   loop around [`StdMonitorGuard::wait`] or [`StdMonitorGuard::wait_timeout`].
65///
66/// A poisoned mutex is recovered by taking the inner state. This makes
67/// `StdMonitor` suitable for coordination state that should remain observable
68/// after another thread panics while holding the lock.
69///
70/// # Difference from `Mutex` and `Condvar`
71///
72/// With the standard library primitives, callers usually store two fields and
73/// manually keep them paired:
74///
75/// ```rust
76/// # use std::sync::{Condvar, Mutex};
77/// # struct State;
78/// struct Shared {
79///     state: Mutex<State>,
80///     changed: Condvar,
81/// }
82/// ```
83///
84/// `StdMonitor<State>` stores the same pair internally. A [`StdMonitorGuard`] is a
85/// wrapper around the standard library's `MutexGuard`; it keeps the protected
86/// state locked and knows which monitor it belongs to, so its wait methods use
87/// the matching condition variable.
88///
89/// # Type Parameters
90///
91/// * `T` - The state protected by this monitor.
92///
93/// # Example
94///
95/// ```rust
96/// use std::thread;
97///
98/// use qubit_lock::ArcStdMonitor;
99///
100/// let monitor = ArcStdMonitor::new(false);
101/// let waiter_monitor = monitor.clone();
102///
103/// let waiter = thread::spawn(move || {
104///     waiter_monitor.wait_until(
105///         |ready| *ready,
106///         |ready| {
107///             *ready = false;
108///         },
109///     );
110/// });
111///
112/// monitor.write(|ready| {
113///     *ready = true;
114/// });
115/// monitor.notify_all();
116///
117/// waiter.join().expect("waiter should finish");
118/// assert!(!monitor.read(|ready| *ready));
119/// ```
120///
121pub struct StdMonitor<T> {
122    /// Mutex protecting the monitor state.
123    state: Mutex<T>,
124    /// Condition variable used to wake predicate waiters after state changes.
125    pub(super) changed: Condvar,
126}
127
128impl<T> StdMonitor<T> {
129    /// Creates a monitor protecting the supplied state value.
130    ///
131    /// # Arguments
132    ///
133    /// * `state` - Initial state protected by the monitor.
134    ///
135    /// # Returns
136    ///
137    /// A monitor initialized with the supplied state.
138    ///
139    /// # Example
140    ///
141    /// ```rust
142    /// use qubit_lock::StdMonitor;
143    ///
144    /// let monitor = StdMonitor::new(0_u32);
145    /// assert_eq!(monitor.read(|n| *n), 0);
146    /// ```
147    #[inline]
148    pub fn new(state: T) -> Self {
149        Self {
150            state: Mutex::new(state),
151            changed: Condvar::new(),
152        }
153    }
154
155    /// Acquires the monitor and returns a guard for explicit state-machine code.
156    ///
157    /// The returned [`StdMonitorGuard`] keeps the monitor mutex locked until the
158    /// guard is dropped. It can also be passed through
159    /// [`StdMonitorGuard::wait`] or [`StdMonitorGuard::wait_timeout`] to temporarily
160    /// release the lock while waiting on this monitor's condition variable.
161    ///
162    /// If the mutex is poisoned, this method recovers the inner state and still
163    /// returns a guard.
164    ///
165    /// # Returns
166    ///
167    /// A guard that provides read and write access to the protected state.
168    ///
169    /// # Example
170    ///
171    /// ```rust
172    /// use qubit_lock::StdMonitor;
173    ///
174    /// let monitor = StdMonitor::new(1);
175    /// {
176    ///     let mut value = monitor.lock();
177    ///     *value += 1;
178    /// }
179    ///
180    /// assert_eq!(monitor.read(|value| *value), 2);
181    /// ```
182    #[inline]
183    pub fn lock(&self) -> StdMonitorGuard<'_, T> {
184        StdMonitorGuard::new(
185            self,
186            self.state
187                .lock()
188                .unwrap_or_else(std::sync::PoisonError::into_inner),
189        )
190    }
191
192    /// Acquires the monitor and reads the protected state.
193    ///
194    /// The closure runs while the mutex is held. Keep the closure short and do
195    /// not call code that may block for a long time.
196    ///
197    /// If the mutex is poisoned, this method recovers the inner state and still
198    /// executes the closure.
199    ///
200    /// # Arguments
201    ///
202    /// * `f` - Closure that receives an immutable reference to the state.
203    ///
204    /// # Returns
205    ///
206    /// The value returned by the closure.
207    ///
208    /// # Example
209    ///
210    /// ```rust
211    /// use qubit_lock::StdMonitor;
212    ///
213    /// let monitor = StdMonitor::new(10_i32);
214    /// let n = monitor.read(|x| *x);
215    /// assert_eq!(n, 10);
216    /// ```
217    #[inline]
218    pub fn read<R, F>(&self, f: F) -> R
219    where
220        F: FnOnce(&T) -> R,
221    {
222        let guard = self.lock();
223        f(&*guard)
224    }
225
226    /// Acquires the monitor and mutates the protected state.
227    ///
228    /// The closure runs while the mutex is held. This method only changes the
229    /// state; callers should explicitly call [`Self::notify_one`] or
230    /// [`Self::notify_all`] after changing a condition that waiters may be
231    /// observing.
232    ///
233    /// If the mutex is poisoned, this method recovers the inner state and still
234    /// executes the closure.
235    ///
236    /// # Arguments
237    ///
238    /// * `f` - Closure that receives a mutable reference to the state.
239    ///
240    /// # Returns
241    ///
242    /// The value returned by the closure.
243    ///
244    /// # Example
245    ///
246    /// ```rust
247    /// use qubit_lock::StdMonitor;
248    ///
249    /// let monitor = StdMonitor::new(String::new());
250    /// let len = monitor.write(|s| {
251    ///     s.push_str("hi");
252    ///     s.len()
253    /// });
254    /// assert_eq!(len, 2);
255    /// ```
256    #[inline]
257    pub fn write<R, F>(&self, f: F) -> R
258    where
259        F: FnOnce(&mut T) -> R,
260    {
261        let mut guard = self.lock();
262        f(&mut *guard)
263    }
264
265    /// Acquires the monitor, mutates the protected state, and wakes one waiter.
266    ///
267    /// The closure runs while the mutex is held. After the closure returns, the
268    /// mutex guard is dropped and one thread waiting on this monitor's condition
269    /// variable is notified. This is a convenience method for the common
270    /// "update state, then notify one waiter" pattern.
271    ///
272    /// If the mutex is poisoned, this method recovers the inner state before
273    /// running the closure. If `f` panics, the panic is propagated and no
274    /// notification is sent.
275    ///
276    /// # Arguments
277    ///
278    /// * `f` - Closure that receives a mutable reference to the state.
279    ///
280    /// # Returns
281    ///
282    /// The value returned by the closure.
283    ///
284    /// # Example
285    ///
286    /// ```rust
287    /// use qubit_lock::StdMonitor;
288    ///
289    /// let monitor = StdMonitor::new(Vec::<i32>::new());
290    /// let len = monitor.write_notify_one(|items| {
291    ///     items.push(7);
292    ///     items.len()
293    /// });
294    ///
295    /// assert_eq!(len, 1);
296    /// ```
297    #[inline]
298    pub fn write_notify_one<R, F>(&self, f: F) -> R
299    where
300        F: FnOnce(&mut T) -> R,
301    {
302        let result = self.write(f);
303        self.notify_one();
304        result
305    }
306
307    /// Acquires the monitor, mutates the protected state, and wakes all waiters.
308    ///
309    /// The closure runs while the mutex is held. After the closure returns, the
310    /// mutex guard is dropped and all threads waiting on this monitor's condition
311    /// variable are notified. This is a convenience method for state changes that
312    /// may allow multiple waiters to make progress.
313    ///
314    /// If the mutex is poisoned, this method recovers the inner state before
315    /// running the closure. If `f` panics, the panic is propagated and no
316    /// notification is sent.
317    ///
318    /// # Arguments
319    ///
320    /// * `f` - Closure that receives a mutable reference to the state.
321    ///
322    /// # Returns
323    ///
324    /// The value returned by the closure.
325    ///
326    /// # Example
327    ///
328    /// ```rust
329    /// use qubit_lock::StdMonitor;
330    ///
331    /// let monitor = StdMonitor::new(false);
332    /// let ready = monitor.write_notify_all(|ready| {
333    ///     *ready = true;
334    ///     *ready
335    /// });
336    ///
337    /// assert!(ready);
338    /// ```
339    #[inline]
340    pub fn write_notify_all<R, F>(&self, f: F) -> R
341    where
342        F: FnOnce(&mut T) -> R,
343    {
344        let result = self.write(f);
345        self.notify_all();
346        result
347    }
348
349    /// Waits for a notification without checking state.
350    ///
351    /// This method locks the monitor, waits once on the condition variable,
352    /// and returns after the wait is woken. Most coordination code should
353    /// prefer [`Self::wait_while`], [`Self::wait_until`], or an explicit
354    /// [`StdMonitorGuard`] loop that rechecks protected state.
355    ///
356    /// If the mutex is poisoned while waiting, this method recovers the inner
357    /// state and returns normally after the wait is woken.
358    ///
359    /// This method may block indefinitely if no notification is sent.
360    #[inline]
361    pub fn wait(&self) {
362        let guard = self.lock();
363        let _guard = guard.wait();
364    }
365
366    /// Waits for a notification or timeout without checking state.
367    ///
368    /// This convenience method locks the monitor, waits once on the condition
369    /// variable, and returns why the timed wait completed. It is useful only
370    /// when the caller genuinely needs a notification wait without inspecting
371    /// state before or after the wait. Most coordination code should prefer
372    /// [`Self::wait_while`], [`Self::wait_until`], or the explicit
373    /// [`StdMonitorGuard::wait_timeout`] loop.
374    ///
375    /// Condition variables may wake spuriously, so
376    /// [`WaitTimeoutStatus::Woken`] does not prove that a notifier changed the
377    /// state.
378    ///
379    /// If the mutex is poisoned, this method recovers the inner state and
380    /// continues waiting.
381    ///
382    /// # Arguments
383    ///
384    /// * `timeout` - Maximum duration to wait for a notification.
385    ///
386    /// # Returns
387    ///
388    /// [`WaitTimeoutStatus::Woken`] if the wait returned before the timeout,
389    /// or [`WaitTimeoutStatus::TimedOut`] if the timeout elapsed.
390    ///
391    /// # Example
392    ///
393    /// ```rust
394    /// use std::time::Duration;
395    ///
396    /// use qubit_lock::{StdMonitor, WaitTimeoutStatus};
397    ///
398    /// let monitor = StdMonitor::new(false);
399    /// let status = monitor.wait_for(Duration::from_millis(1));
400    ///
401    /// assert_eq!(status, WaitTimeoutStatus::TimedOut);
402    /// ```
403    #[inline]
404    pub fn wait_for(&self, timeout: Duration) -> WaitTimeoutStatus {
405        let guard = self.lock();
406        let (_guard, status) = guard.wait_timeout(timeout);
407        status
408    }
409
410    /// Waits while a predicate remains true, then mutates the protected state.
411    ///
412    /// This is the monitor equivalent of the common `while condition { wait }`
413    /// guarded-suspension pattern. The predicate is evaluated while holding the
414    /// mutex. If it returns `true`, the current thread waits on the condition
415    /// variable and atomically releases the mutex. After a notification or
416    /// spurious wakeup, the mutex is reacquired and the predicate is evaluated
417    /// again. When the predicate returns `false`, `f` runs while the mutex is
418    /// still held.
419    ///
420    /// This method may block indefinitely if no thread changes the state so
421    /// that `waiting` becomes false and sends a notification.
422    ///
423    /// If the mutex is poisoned before or during the wait, this method recovers
424    /// the inner state and continues waiting or executes the closure.
425    ///
426    /// # Arguments
427    ///
428    /// * `waiting` - Predicate that returns `true` while the caller should
429    ///   keep waiting.
430    /// * `f` - Closure that receives mutable access after waiting is no longer
431    ///   required.
432    ///
433    /// # Returns
434    ///
435    /// The value returned by `f`.
436    ///
437    /// # Example
438    ///
439    /// ```rust
440    /// use std::{
441    ///     sync::Arc,
442    ///     thread,
443    /// };
444    ///
445    /// use qubit_lock::StdMonitor;
446    ///
447    /// let monitor = Arc::new(StdMonitor::new(Vec::<i32>::new()));
448    /// let worker_monitor = Arc::clone(&monitor);
449    ///
450    /// let worker = thread::spawn(move || {
451    ///     worker_monitor.wait_while(
452    ///         |items| items.is_empty(),
453    ///         |items| items.pop().expect("item should be ready"),
454    ///     )
455    /// });
456    ///
457    /// monitor.write(|items| items.push(7));
458    /// monitor.notify_one();
459    ///
460    /// assert_eq!(worker.join().expect("worker should finish"), 7);
461    /// ```
462    #[inline]
463    pub fn wait_while<R, P, F>(&self, mut waiting: P, f: F) -> R
464    where
465        P: FnMut(&T) -> bool,
466        F: FnOnce(&mut T) -> R,
467    {
468        let mut guard = self.lock();
469        while waiting(&*guard) {
470            guard = guard.wait();
471        }
472        f(&mut *guard)
473    }
474
475    /// Waits until the protected state satisfies a predicate, then mutates it.
476    ///
477    /// This is the positive-predicate counterpart of [`Self::wait_while`]. The
478    /// predicate is evaluated while holding the mutex. If it returns `false`,
479    /// the current thread waits on the condition variable and atomically
480    /// releases the mutex. After a notification or spurious wakeup, the mutex
481    /// is reacquired and the predicate is evaluated again. When the predicate
482    /// returns `true`, `f` runs while the mutex is still held.
483    ///
484    /// This method may block indefinitely if no thread changes the state to
485    /// satisfy the predicate and sends a notification.
486    ///
487    /// If the mutex is poisoned before or during the wait, this method recovers
488    /// the inner state and continues waiting or executes the closure.
489    ///
490    /// # Arguments
491    ///
492    /// * `ready` - Predicate that returns `true` when the state is ready.
493    /// * `f` - Closure that receives mutable access to the ready state.
494    ///
495    /// # Returns
496    ///
497    /// The value returned by `f` after the predicate has become true.
498    ///
499    /// # Example
500    ///
501    /// ```rust
502    /// use std::{
503    ///     sync::Arc,
504    ///     thread,
505    /// };
506    ///
507    /// use qubit_lock::StdMonitor;
508    ///
509    /// let monitor = Arc::new(StdMonitor::new(false));
510    /// let waiter_monitor = Arc::clone(&monitor);
511    ///
512    /// let waiter = thread::spawn(move || {
513    ///     waiter_monitor.wait_until(
514    ///         |ready| *ready,
515    ///         |ready| {
516    ///             *ready = false;
517    ///             "done"
518    ///         },
519    ///     )
520    /// });
521    ///
522    /// monitor.write(|ready| *ready = true);
523    /// monitor.notify_one();
524    ///
525    /// assert_eq!(waiter.join().expect("waiter should finish"), "done");
526    /// ```
527    #[inline]
528    pub fn wait_until<R, P, F>(&self, mut ready: P, f: F) -> R
529    where
530        P: FnMut(&T) -> bool,
531        F: FnOnce(&mut T) -> R,
532    {
533        self.wait_while(|state| !ready(state), f)
534    }
535
536    /// Waits while a predicate remains true, with an overall time limit.
537    ///
538    /// This method is the timeout-aware form of [`Self::wait_while`]. It keeps
539    /// rechecking `waiting` under the monitor lock and waits only for the
540    /// remaining portion of `timeout`. If `waiting` becomes false before the
541    /// timeout expires, `f` runs while the lock is still held. If the timeout
542    /// expires first, the closure is not called.
543    ///
544    /// Condition variables may wake spuriously, and timeout status alone is not
545    /// used as proof that the predicate is still true; the predicate is always
546    /// rechecked under the lock.
547    ///
548    /// If the mutex is poisoned before or during the wait, this method recovers
549    /// the inner state and continues waiting or executes the closure.
550    ///
551    /// # Arguments
552    ///
553    /// * `timeout` - Maximum total duration to wait.
554    /// * `waiting` - Predicate that returns `true` while the caller should
555    ///   continue waiting.
556    /// * `f` - Closure that receives mutable access when waiting is no longer
557    ///   required.
558    ///
559    /// # Returns
560    ///
561    /// [`WaitTimeoutResult::Ready`] with the value returned by `f` when the
562    /// predicate stops blocking before the timeout. Returns
563    /// [`WaitTimeoutResult::TimedOut`] when the timeout expires first.
564    ///
565    /// # Example
566    ///
567    /// ```rust
568    /// use std::time::Duration;
569    ///
570    /// use qubit_lock::{StdMonitor, WaitTimeoutResult};
571    ///
572    /// let monitor = StdMonitor::new(Vec::<i32>::new());
573    /// let result = monitor.wait_while_for(
574    ///     Duration::from_millis(1),
575    ///     |items| items.is_empty(),
576    ///     |items| items.pop(),
577    /// );
578    ///
579    /// assert_eq!(result, WaitTimeoutResult::TimedOut);
580    /// ```
581    #[inline]
582    pub fn wait_while_for<R, P, F>(
583        &self,
584        timeout: Duration,
585        mut waiting: P,
586        f: F,
587    ) -> WaitTimeoutResult<R>
588    where
589        P: FnMut(&T) -> bool,
590        F: FnOnce(&mut T) -> R,
591    {
592        let mut guard = self.lock();
593        let start = Instant::now();
594        loop {
595            if !waiting(&*guard) {
596                return WaitTimeoutResult::Ready(f(&mut *guard));
597            }
598
599            let elapsed = start.elapsed();
600            let remaining = timeout.checked_sub(elapsed).unwrap_or_default();
601            if remaining.is_zero() {
602                return WaitTimeoutResult::TimedOut;
603            }
604
605            let (next_guard, _status) = guard.wait_timeout(remaining);
606            guard = next_guard;
607        }
608    }
609
610    /// Waits until a predicate becomes true, with an overall time limit.
611    ///
612    /// This is the positive-predicate counterpart of
613    /// [`Self::wait_while_for`]. If `ready` becomes true before the timeout
614    /// expires, `f` runs while the monitor lock is still held. If the timeout
615    /// expires first, the closure is not called.
616    ///
617    /// Condition variables may wake spuriously, and timeout status alone is not
618    /// used as proof that the predicate is still false; the predicate is always
619    /// rechecked under the lock.
620    ///
621    /// If the mutex is poisoned before or during the wait, this method recovers
622    /// the inner state and continues waiting or executes the closure.
623    ///
624    /// # Arguments
625    ///
626    /// * `timeout` - Maximum total duration to wait.
627    /// * `ready` - Predicate that returns `true` when the caller may continue.
628    /// * `f` - Closure that receives mutable access to the ready state.
629    ///
630    /// # Returns
631    ///
632    /// [`WaitTimeoutResult::Ready`] with the value returned by `f` when the
633    /// predicate becomes true before the timeout. Returns
634    /// [`WaitTimeoutResult::TimedOut`] when the timeout expires first.
635    ///
636    /// # Example
637    ///
638    /// ```rust
639    /// use std::{
640    ///     sync::Arc,
641    ///     thread,
642    ///     time::Duration,
643    /// };
644    ///
645    /// use qubit_lock::{StdMonitor, WaitTimeoutResult};
646    ///
647    /// let monitor = Arc::new(StdMonitor::new(false));
648    /// let waiter_monitor = Arc::clone(&monitor);
649    ///
650    /// let waiter = thread::spawn(move || {
651    ///     waiter_monitor.wait_until_for(
652    ///         Duration::from_secs(1),
653    ///         |ready| *ready,
654    ///         |ready| {
655    ///             *ready = false;
656    ///             5
657    ///         },
658    ///     )
659    /// });
660    ///
661    /// monitor.write(|ready| *ready = true);
662    /// monitor.notify_one();
663    ///
664    /// assert_eq!(
665    ///     waiter.join().expect("waiter should finish"),
666    ///     WaitTimeoutResult::Ready(5),
667    /// );
668    /// ```
669    #[inline]
670    pub fn wait_until_for<R, P, F>(
671        &self,
672        timeout: Duration,
673        mut ready: P,
674        f: F,
675    ) -> WaitTimeoutResult<R>
676    where
677        P: FnMut(&T) -> bool,
678        F: FnOnce(&mut T) -> R,
679    {
680        self.wait_while_for(timeout, |state| !ready(state), f)
681    }
682
683    /// Wakes one thread waiting on this monitor's condition variable.
684    ///
685    /// Notifications do not carry state by themselves. A waiting thread only
686    /// proceeds safely after rechecking the protected state. Call this after
687    /// changing state that may make one waiter able to continue.
688    ///
689    /// # Example
690    ///
691    /// ```rust
692    /// use std::thread;
693    ///
694    /// use qubit_lock::ArcStdMonitor;
695    ///
696    /// let monitor = ArcStdMonitor::new(0_u32);
697    /// let waiter = {
698    ///     let m = monitor.clone();
699    ///     thread::spawn(move || {
700    ///         m.wait_until(|n| *n > 0, |n| {
701    ///             *n -= 1;
702    ///         });
703    ///     })
704    /// };
705    ///
706    /// monitor.write(|n| *n = 1);
707    /// monitor.notify_one();
708    /// waiter.join().expect("waiter should finish");
709    /// ```
710    #[inline]
711    pub fn notify_one(&self) {
712        self.changed.notify_one();
713    }
714
715    /// Wakes all threads waiting on this monitor's condition variable.
716    ///
717    /// Notifications do not carry state by themselves. Every awakened thread
718    /// must recheck the protected state before continuing. Call this after a
719    /// state change that may allow multiple waiters to make progress.
720    ///
721    /// # Example
722    ///
723    /// ```rust
724    /// use std::thread;
725    ///
726    /// use qubit_lock::ArcStdMonitor;
727    ///
728    /// let monitor = ArcStdMonitor::new(false);
729    /// let mut handles = Vec::new();
730    /// for _ in 0..2 {
731    ///     let m = monitor.clone();
732    ///     handles.push(thread::spawn(move || {
733    ///         m.wait_until(|ready| *ready, |_| ());
734    ///     }));
735    /// }
736    ///
737    /// monitor.write(|ready| *ready = true);
738    /// monitor.notify_all();
739    /// for h in handles {
740    ///     h.join().expect("waiter should finish");
741    /// }
742    /// ```
743    #[inline]
744    pub fn notify_all(&self) {
745        self.changed.notify_all();
746    }
747}
748
749impl<T> Notifier for StdMonitor<T> {
750    /// Wakes one thread waiting on this monitor.
751    #[inline]
752    fn notify_one(&self) {
753        Self::notify_one(self);
754    }
755
756    /// Wakes all threads waiting on this monitor.
757    #[inline]
758    fn notify_all(&self) {
759        Self::notify_all(self);
760    }
761}
762
763impl<T> NotificationWaiter for StdMonitor<T> {
764    /// Blocks until a notification wakes this waiter.
765    #[inline]
766    fn wait(&self) {
767        Self::wait(self);
768    }
769}
770
771impl<T> TimeoutNotificationWaiter for StdMonitor<T> {
772    /// Blocks until a notification wakes this waiter or the timeout expires.
773    #[inline]
774    fn wait_for(&self, timeout: Duration) -> WaitTimeoutStatus {
775        Self::wait_for(self, timeout)
776    }
777}
778
779impl<T> ConditionWaiter for StdMonitor<T> {
780    type State = T;
781
782    /// Blocks until the predicate becomes true, then runs the action.
783    #[inline]
784    fn wait_until<R, P, F>(&self, predicate: P, action: F) -> R
785    where
786        P: FnMut(&Self::State) -> bool,
787        F: FnOnce(&mut Self::State) -> R,
788    {
789        Self::wait_until(self, predicate, action)
790    }
791
792    /// Blocks while the predicate remains true, then runs the action.
793    #[inline]
794    fn wait_while<R, P, F>(&self, predicate: P, action: F) -> R
795    where
796        P: FnMut(&Self::State) -> bool,
797        F: FnOnce(&mut Self::State) -> R,
798    {
799        Self::wait_while(self, predicate, action)
800    }
801}
802
803impl<T> TimeoutConditionWaiter for StdMonitor<T> {
804    /// Blocks until the predicate becomes true or the timeout expires.
805    #[inline]
806    fn wait_until_for<R, P, F>(
807        &self,
808        timeout: Duration,
809        predicate: P,
810        action: F,
811    ) -> WaitTimeoutResult<R>
812    where
813        P: FnMut(&Self::State) -> bool,
814        F: FnOnce(&mut Self::State) -> R,
815    {
816        Self::wait_until_for(self, timeout, predicate, action)
817    }
818
819    /// Blocks while the predicate remains true or until the timeout expires.
820    #[inline]
821    fn wait_while_for<R, P, F>(
822        &self,
823        timeout: Duration,
824        predicate: P,
825        action: F,
826    ) -> WaitTimeoutResult<R>
827    where
828        P: FnMut(&Self::State) -> bool,
829        F: FnOnce(&mut Self::State) -> R,
830    {
831        Self::wait_while_for(self, timeout, predicate, action)
832    }
833}
834
835impl<T> From<T> for StdMonitor<T> {
836    /// Creates a standard monitor from an initial state value.
837    ///
838    /// # Arguments
839    ///
840    /// * `value` - Initial state protected by the monitor.
841    ///
842    /// # Returns
843    ///
844    /// A standard monitor initialized with `value`.
845    #[inline]
846    fn from(value: T) -> Self {
847        Self::new(value)
848    }
849}
850
851impl<T: Default> Default for StdMonitor<T> {
852    /// Creates a monitor containing `T::default()`.
853    ///
854    /// # Returns
855    ///
856    /// A monitor protecting the default value for `T`.
857    ///
858    /// # Example
859    ///
860    /// ```rust
861    /// use qubit_lock::StdMonitor;
862    ///
863    /// let monitor: StdMonitor<String> = StdMonitor::default();
864    /// assert!(monitor.read(|s| s.is_empty()));
865    /// ```
866    #[inline]
867    fn default() -> Self {
868        Self::new(T::default())
869    }
870}