Skip to main content

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