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}