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}