timer_deque_rs/lib.rs
1/*-
2 * timer-rs - a Rust crate which provides timer and timer queues based on target OS
3 * functionality.
4 *
5 * Copyright (C) 2025 Aleksandr Morozov
6 *
7 * The timer-rs crate can be redistributed and/or modified
8 * under the terms of either of the following licenses:
9 *
10 * 1. the Mozilla Public License Version 2.0 (the “MPL”) OR
11 *
12 * 2. EUROPEAN UNION PUBLIC LICENCE v. 1.2 EUPL © the European Union 2007, 2016
13 */
14
15//! # timer-deque-rs
16//!
17//! Three deque types:
18//!
19//! [TimerDequeueConsumer] consumes the item and places it on the queue.
20//! ```ignore
21//! let mut time_list =
22//! OrderedTimerDeque
23//! ::<TimerDequeueConsumer<TestItem>>
24//! ::new("test_label".into(), 4, false).unwrap();
25//! ```
26//!
27//!
28//! [TimerDequeueSignalTicket] sends signal as specified in the callback(non-blocking) for every added item.
29//! ```ignore
30//! let mut time_list =
31//! OrderedTimerDeque
32//! ::<TimerDequeueSignalTicket<TestSigStruct>>
33//! ::new("test_label".into(), 4, false).unwrap();
34//! ```
35//!
36//!
37//! [TimerDequeueTicketIssuer] issues a ticket which can be dropped (deallocated), so timer would ignore item.
38//! ```ignore
39//! let mut time_list =
40//! OrderedTimerDeque
41//! ::<TimerDequeueTicketIssuer>
42//! ::new("test_label".into(), 4, false).unwrap();
43//! ```
44//!
45//!
46//! ## Timers polling
47//!
48//! For the `sync` a `Epoll` for Linux and `Kqueue` for BSD are used. Both are
49//! wrapped into [TimerPoll].
50//!
51//! ```ignore
52//! let ev_watch = TimerPoll::new().unwrap();
53//!
54//! let mut time_list =
55//! OrderedTimerDeque
56//! ::<TimerDequeueConsumer<Arc<TestItem>>>
57//! ::new("test_label".into(), 4, false).unwrap();
58//!
59//! // add timer to event
60//! ev_watch.add(&time_list).unwrap();
61//! ```
62//! In case if monitored timer, for example, `time_list` from above exmaple would be dropped intentionally or
63//! by acident, it will be automatically removed from the poll queue. If, for any reason the `ev_watch` becomes
64//! invalid i.e dropped, all added instances will be unbinded from this [TimerPoll] instance and can be reused.
65//!
66//! Alternativly, [OrderedTimerDeque] provides blocking/nonblocking function
67//! `wait_for_event` which is less efficient.
68//!
69//! For the `async` a [Future] is implemented. Polling `future` is not too
70//! efficient (the same situation with `wait_for_event`).
71//!
72//! ```ignore
73//! let mut time_list =
74//! OrderedTimerDeque
75//! ::<TimerDequeueConsumer<Arc<TestItem>>>
76//! ::new("test_label_async".into(), 4, false)
77//! .unwrap();
78//!
79//! let res = time_list.poll().await.unwrap();
80//!
81//! // ...
82//! // read timeout items
83//! time_list.timeout_event_handler(res, &mut timeout_items).unwrap();
84//! ```
85//!
86//! For more efficient `polling` of Timer for event, use async crates like
87//! `smol`, `tokio` or other. In case of `tokio` an `AsyncFd can be used.`
88//!
89//! ```ignore
90//! let time_list =
91//! OrderedTimerDeque
92//! ::<TimerDequeueSignalTicket<TestStruct>>
93//! ::new("test_label".into(), 4, false)
94//! .unwrap();
95//!
96//! let mut async_time_list = AsyncFd::new(time_list).unwrap();
97//!
98//!
99//! // poll the timer until it becomes ready
100//! let mut read_guard =
101//! async_time_list.ready_mut(Interest::READABLE).await.unwrap();
102//!
103//! // clear ready otherwise it will return WOULDBLOCK
104//! read_guard.clear_ready();
105//!
106//! // read events
107//! let res = read_guard.get_inner().wait_for_event().unwrap();
108//! ```
109//!
110//! ## Timer
111//!
112//! A timer can be used directly.
113//!
114//! ```ignore
115//! // timer init as blocking
116//! let timer =
117//! TimerFd::new(Cow::Borrowed("test"), TimerType::CLOCK_REALTIME, TimerFlags::empty()).unwrap();
118//!
119//! let now = chrono::offset::Local::now().timestamp();
120//! let snow = now + 3;
121//! let s = Instant::now();
122//!
123//! // setting timer
124//! let res =
125//! timer.set_time(TimerSetTimeFlags::TFD_TIMER_ABSTIME, TimerExpMode::OneShot{sec: snow, nsec: 0});
126//!
127//! // read timer
128//! let ovf = timer.read().unwrap().unwrap();
129//! ```
130//!
131//! The abobe is not too efficient because in case of `nonblocking`, it will return none immidiatly and
132//! in case of `blocking` it would block thread.
133//!
134//! A `Epoll`, `Select`, `KQueue` can be used to poll timer more efficient. Or, for example, `AsyncFd` from
135//! `tokio` can be used too.
136
137pub extern crate nix;
138pub extern crate bitflags;
139pub extern crate chrono;
140pub extern crate rand;
141
142/// All code which should be ported to the specific OS. Contains a system timer
143/// implementation and poll.
144pub mod timer_portable;
145
146/// Crates error handling.
147pub mod error;
148
149/// Common things.
150pub mod common;
151
152/// A `consumer` type of the timer which consumes the intance and returns it when
153/// timer triggers. The `consumed` instance normally whould be [Send] because it will
154/// be moved into the timer.
155pub mod timer_consumer;
156
157/// A `ticket` issuer. Issues a ticket which should be assigned to the instance whcih was added
158/// to the timer's queue. The `ticket` can be used to remove the item from queue before the
159/// timeout event. If ticket is dropped i.e connection closed, the ticket will be
160/// in timer's queue until timeout where it will be ignored on timeout event.
161pub mod timer_tickets;
162
163/// A `signal` sender. Calls the specified callback which must never block the executing thread.
164pub mod timer_signal;
165
166/// A base implementation of the sorted timer queue.
167pub mod timer;
168
169#[cfg(test)]
170mod tests;
171
172pub use timer::OrderedTimerDeque;
173
174pub use timer_consumer::TimerDequeueConsumer;
175pub use timer_signal::{TimerDequeueSignal, TimerDequeueSignalTicket};
176pub use timer_tickets::{TimerDequeueTicketIssuer, TimerDequeueTicket, TimerDequeueId};
177
178pub use timer_portable::{TimerPoll, TimerReadRes, FdTimerCom};