Skip to main content

qubit_lock/monitor/
arc_tokio_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//! Arc-wrapped Tokio monitor.
11
12use std::{
13    ops::Deref,
14    sync::Arc,
15    time::Duration,
16};
17
18use super::{
19    AsyncConditionWaiter,
20    AsyncMonitorFuture,
21    AsyncNotificationWaiter,
22    AsyncTimeoutConditionWaiter,
23    AsyncTimeoutNotificationWaiter,
24    Notifier,
25    TokioMonitor,
26    WaitTimeoutResult,
27    WaitTimeoutStatus,
28};
29
30/// Cloneable handle around a [`TokioMonitor`].
31pub struct ArcTokioMonitor<T> {
32    /// Shared Tokio monitor.
33    inner: Arc<TokioMonitor<T>>,
34}
35
36impl<T> ArcTokioMonitor<T> {
37    /// Creates an Arc-wrapped Tokio monitor.
38    ///
39    /// # Arguments
40    ///
41    /// * `state` - Initial protected state.
42    ///
43    /// # Returns
44    ///
45    /// A cloneable Tokio monitor handle.
46    pub fn new(state: T) -> Self {
47        Self {
48            inner: Arc::new(TokioMonitor::new(state)),
49        }
50    }
51
52    /// Reads protected state asynchronously.
53    pub async fn async_read<R, F>(&self, f: F) -> R
54    where
55        F: FnOnce(&T) -> R,
56    {
57        self.inner.async_read(f).await
58    }
59
60    /// Mutates protected state asynchronously without notifying.
61    pub async fn async_write<R, F>(&self, f: F) -> R
62    where
63        F: FnOnce(&mut T) -> R,
64    {
65        self.inner.async_write(f).await
66    }
67
68    /// Mutates protected state asynchronously and wakes one waiter.
69    pub async fn async_write_notify_one<R, F>(&self, f: F) -> R
70    where
71        F: FnOnce(&mut T) -> R,
72    {
73        self.inner.async_write_notify_one(f).await
74    }
75
76    /// Mutates protected state asynchronously and wakes all waiters.
77    pub async fn async_write_notify_all<R, F>(&self, f: F) -> R
78    where
79        F: FnOnce(&mut T) -> R,
80    {
81        self.inner.async_write_notify_all(f).await
82    }
83
84    /// Wakes one async waiter.
85    pub fn notify_one(&self) {
86        self.inner.notify_one();
87    }
88
89    /// Wakes all async waiters.
90    pub fn notify_all(&self) {
91        self.inner.notify_all();
92    }
93}
94
95impl<T> Notifier for ArcTokioMonitor<T> {
96    /// Wakes one async waiter.
97    fn notify_one(&self) {
98        Self::notify_one(self);
99    }
100
101    /// Wakes all async waiters.
102    fn notify_all(&self) {
103        Self::notify_all(self);
104    }
105}
106
107impl<T: Send> AsyncNotificationWaiter for ArcTokioMonitor<T> {
108    /// Returns a future that resolves after an async notification.
109    fn async_wait<'a>(&'a self) -> AsyncMonitorFuture<'a, ()> {
110        self.inner.async_wait()
111    }
112}
113
114impl<T: Send> AsyncTimeoutNotificationWaiter for ArcTokioMonitor<T> {
115    /// Returns a future that resolves after notification or timeout.
116    fn async_wait_for<'a>(
117        &'a self,
118        timeout: Duration,
119    ) -> AsyncMonitorFuture<'a, WaitTimeoutStatus> {
120        self.inner.async_wait_for(timeout)
121    }
122}
123
124impl<T: Send> AsyncConditionWaiter for ArcTokioMonitor<T> {
125    type State = T;
126
127    /// Returns a future that waits until the predicate becomes true.
128    fn async_wait_until<'a, R, P, F>(&'a self, predicate: P, action: F) -> AsyncMonitorFuture<'a, R>
129    where
130        R: Send + 'a,
131        P: FnMut(&Self::State) -> bool + Send + 'a,
132        F: FnOnce(&mut Self::State) -> R + Send + 'a,
133    {
134        self.inner.async_wait_until(predicate, action)
135    }
136
137    /// Returns a future that waits while the predicate remains true.
138    fn async_wait_while<'a, R, P, F>(&'a self, predicate: P, action: F) -> AsyncMonitorFuture<'a, R>
139    where
140        R: Send + 'a,
141        P: FnMut(&Self::State) -> bool + Send + 'a,
142        F: FnOnce(&mut Self::State) -> R + Send + 'a,
143    {
144        self.inner.async_wait_while(predicate, action)
145    }
146}
147
148impl<T: Send> AsyncTimeoutConditionWaiter for ArcTokioMonitor<T> {
149    /// Returns a future that waits until the predicate becomes true or times out.
150    fn async_wait_until_for<'a, R, P, F>(
151        &'a self,
152        timeout: Duration,
153        predicate: P,
154        action: F,
155    ) -> AsyncMonitorFuture<'a, WaitTimeoutResult<R>>
156    where
157        R: Send + 'a,
158        P: FnMut(&Self::State) -> bool + Send + 'a,
159        F: FnOnce(&mut Self::State) -> R + Send + 'a,
160    {
161        self.inner.async_wait_until_for(timeout, predicate, action)
162    }
163
164    /// Returns a future that waits while the predicate remains true or times out.
165    fn async_wait_while_for<'a, R, P, F>(
166        &'a self,
167        timeout: Duration,
168        predicate: P,
169        action: F,
170    ) -> AsyncMonitorFuture<'a, WaitTimeoutResult<R>>
171    where
172        R: Send + 'a,
173        P: FnMut(&Self::State) -> bool + Send + 'a,
174        F: FnOnce(&mut Self::State) -> R + Send + 'a,
175    {
176        self.inner.async_wait_while_for(timeout, predicate, action)
177    }
178}
179
180impl<T> AsRef<TokioMonitor<T>> for ArcTokioMonitor<T> {
181    /// Returns a reference to the wrapped Tokio monitor.
182    fn as_ref(&self) -> &TokioMonitor<T> {
183        self.inner.as_ref()
184    }
185}
186
187impl<T> Deref for ArcTokioMonitor<T> {
188    type Target = TokioMonitor<T>;
189
190    /// Dereferences to the wrapped Tokio monitor.
191    fn deref(&self) -> &Self::Target {
192        self.inner.as_ref()
193    }
194}
195
196impl<T> Clone for ArcTokioMonitor<T> {
197    /// Clones this shared Tokio monitor handle.
198    fn clone(&self) -> Self {
199        Self {
200            inner: self.inner.clone(),
201        }
202    }
203}
204
205impl<T> From<T> for ArcTokioMonitor<T> {
206    /// Creates an Arc-wrapped Tokio monitor from an initial state value.
207    fn from(value: T) -> Self {
208        Self::new(value)
209    }
210}
211
212impl<T: Default> Default for ArcTokioMonitor<T> {
213    /// Creates an Arc-wrapped Tokio monitor containing `T::default()`.
214    fn default() -> Self {
215        Self::new(T::default())
216    }
217}