Skip to main content

qubit_clock/timer/
manual_timer.rs

1// =============================================================================
2//    Copyright (c) 2025 - 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Defines a timer driven by explicitly advanced monotonic time.
9
10use crate::timer::internal::manual_timer_future::ManualTimerFuture;
11use crate::{
12    ManualMonotonicClock,
13    MonotonicClock,
14    MonotonicInstant,
15    TimeError,
16    Timer,
17    TimerFuture,
18};
19use std::sync::Arc;
20
21/// An asynchronous timer driven by one manual monotonic time domain.
22///
23/// Registrations are visible through the source clock's coordination APIs
24/// before this timer returns their futures. The timer and its futures retain a
25/// private same-domain clock handle, so they remain valid if the source clock
26/// value is dropped.
27#[derive(Debug)]
28pub struct ManualTimer {
29    /// Private handle retaining the manual clock domain and mutable timeline.
30    clock: Arc<ManualMonotonicClock>,
31}
32
33impl ManualTimer {
34    /// Creates a timer sharing the supplied manual clock's exact time domain.
35    ///
36    /// # Parameters
37    ///
38    /// * `clock` - Manual clock whose domain and timeline drive this timer.
39    ///
40    /// # Returns
41    ///
42    /// An independent timer handle retaining the same manual time domain.
43    #[must_use]
44    #[inline]
45    pub fn from_clock(clock: &ManualMonotonicClock) -> Self {
46        Self {
47            clock: Arc::new(clock.same_domain_handle()),
48        }
49    }
50}
51
52impl Timer for ManualTimer {
53    /// Returns the private same-domain manual clock handle.
54    ///
55    /// # Returns
56    ///
57    /// The monotonic clock driving this timer.
58    #[inline(always)]
59    fn clock(&self) -> &dyn MonotonicClock {
60        self.clock.as_ref()
61    }
62
63    /// Eagerly registers an absolute deadline with the manual clock.
64    ///
65    /// # Parameters
66    ///
67    /// * `deadline` - Deadline in this timer's manual clock domain.
68    ///
69    /// # Returns
70    ///
71    /// A cancellation-safe future whose registration is already active.
72    ///
73    /// # Errors
74    ///
75    /// Returns [`TimeError::ClockDomainMismatch`] for a foreign deadline.
76    ///
77    /// # Panics
78    ///
79    /// Panics when waiter identifiers are exhausted or when a reached
80    /// observer waker panics during registration notification.
81    #[inline]
82    fn at(&self, deadline: MonotonicInstant) -> Result<TimerFuture, TimeError> {
83        let future =
84            ManualTimerFuture::register(Arc::clone(&self.clock), deadline)?;
85        Ok(Box::pin(future))
86    }
87}