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