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//! ## A crate which combines a timer with the different deque types.
18//! 
19//! <img src="https://gitlab.com/4neko/timer-rs/-/raw/master/logo_600.png?ref_type=heads&inline=true" width="280"/> <img src="https://gitlab.com/4neko/timer-rs/-/raw/master/source_avail.png?ref_type=heads&inline=true" width="280"/> <img src="https://gitlab.com/4neko/timer-rs/-/raw/master/mpl_or_eupl.png?ref_type=heads&inline=true" width="280"/>
20//! 
21//! ### Two deque opeartion modes:
22//! 
23//! * [OrderdTimerDequeOnce] - after a timeout an item is removed from the queue.
24//! 
25//! * [OrderdTimerDequePeriodic] - after the timeout an item's timeout is extended 
26//!     and item is returned back to queue. It should be manually removed.
27//! 
28//! ### Three deque types:
29//! 
30//! [TimerDequeueConsumer] consumes the item and places it on the queue.
31//! ```ignore
32//! let mut time_list = 
33//!         OrderedTimerDeque
34//!             ::<TimerDequeueConsumer<TestItem, OrderdTimerDequeOnce>>
35//!             ::new("test_label".into(), 4, false).unwrap();
36//! ```
37//! or
38//! ```ignore
39//! let mut time_list = 
40//!         OrderedTimerDeque
41//!             ::<TimerDequeueConsumer<TestItem, OrderdTimerDequePeriodic>>
42//!             ::new("test_label".into(), 4, false).unwrap();
43//! ```
44//! 
45//! [TimerDequeueSignalTicket] sends signal as specified in the callback(non-blocking) for every added item.
46//! ```ignore
47//! let mut time_list = 
48//!         OrderedTimerDeque
49//!             ::<TimerDequeueSignalTicket<TestSigStruct, OrderdTimerDequeOnce>>
50//!             ::new("test_label".into(), 4, false).unwrap();
51//! ```
52//! or
53//! ```ignore
54//! let mut time_list = 
55//!         OrderedTimerDeque
56//!             ::<TimerDequeueSignalTicket<TestSigStruct, OrderdTimerDequePeriodic>>
57//!             ::new("test_label".into(), 4, false).unwrap();
58//! ```
59//! 
60//! 
61//! [TimerDequeueTicketIssuer] issues a ticket which can be dropped (deallocated), so timer would ignore item.
62//! ```ignore
63//! let mut time_list = 
64//!     OrderedTimerDeque
65//!         ::<TimerDequeueTicketIssuer<OrderdTimerDequeOnce>>
66//!         ::new("test_label".into(), 4, false).unwrap();
67//! ```
68//! or
69//! ```ignore
70//! let mut time_list = 
71//!     OrderedTimerDeque
72//!         ::<TimerDequeueTicketIssuer<OrderdTimerDequePeriodic>>
73//!         ::new("test_label".into(), 4, false).unwrap();
74//! ```
75//! 
76//! 
77//! ## Timers polling
78//! 
79//! For the `sync` a `Epoll` for Linux and `Kqueue` for BSD are used. Both are
80//! wrapped into [TimerPoll].
81//! 
82//! ```ignore
83//! let ev_watch = TimerPoll::new().unwrap();
84//! 
85//! let mut time_list = 
86//!     OrderedTimerDeque
87//!         ::<TimerDequeueConsumer<Arc<TestItem>, OrderdTimerDequeOnce>>
88//!         ::new("test_label".into(), 4, false).unwrap();
89//! 
90//!    // add timer to event 
91//! ev_watch.add(&time_list).unwrap();
92//! ```
93//! In case if monitored timer, for example, `time_list` from above exmaple would be dropped intentionally or
94//! by acident, it will be automatically removed from the poll queue. If, for any reason the `ev_watch` becomes
95//! invalid i.e dropped, all added instances will be unbinded from this [TimerPoll] instance and can be reused.
96//! 
97//! Alternativly, [OrderedTimerDeque] provides blocking/nonblocking function
98//! `wait_for_event` which is less efficient.
99//! 
100//! For the `async` a [Future] is implemented. Polling `future` is not too 
101//! efficient (the same situation with `wait_for_event`).
102//! 
103//! ```ignore
104//! let mut time_list = 
105//!     OrderedTimerDeque
106//!         ::<TimerDequeueConsumer<Arc<TestItem>, OrderdTimerDequeOnce>>
107//!         ::new("test_label_async".into(), 4, false)
108//!             .unwrap();
109//! 
110//! let res = time_list.poll().await.unwrap();
111//! 
112//! // ...
113//! // read timeout items
114//! time_list.timeout_event_handler(res, &mut timeout_items).unwrap();
115//! ```
116//! 
117//! For more efficient `polling` of Timer for event, use async crates like
118//! `smol`, `tokio` or other. In case of `tokio` an `AsyncFd can be used.`
119//! 
120//! ```ignore
121//! let time_list = 
122//!     OrderedTimerDeque
123//!         ::<TimerDequeueSignalTicket<TestStruct>, OrderdTimerDequeOnce>
124//!         ::new("test_label".into(), 4, false)
125//!             .unwrap();
126//! 
127//! let mut async_time_list = AsyncFd::new(time_list).unwrap();
128//! 
129//! 
130//! // poll the timer until it becomes ready
131//! let mut read_guard = 
132//!     async_time_list.ready_mut(Interest::READABLE).await.unwrap();
133//! 
134//! // clear ready otherwise it will return WOULDBLOCK
135//! read_guard.clear_ready();
136//! 
137//! // read events
138//! let res = read_guard.get_inner().wait_for_event().unwrap();
139//! ```
140//! 
141//! ## Timer
142//! 
143//! A timer can be used directly.
144//! 
145//! ```ignore
146//! // timer init as blocking
147//! let timer = 
148//!     TimerFd::new(Cow::Borrowed("test"), TimerType::CLOCK_REALTIME, TimerFlags::empty()).unwrap();
149//! 
150//! // setting the timout and timer mode
151//! let abs_time = AbsoluteTime::now().add_sec(3);
152//! 
153//! // the flags will be set automatically
154//! let exp_time = 
155//!     TimerExpMode::<AbsoluteTime>::new_oneshot(abs_time);
156//!
157//! // setting timer
158//!    let res = 
159//!        timer.set_time(exp_time);
160//! 
161//! // read timer
162//! let ovf = timer.read().unwrap().unwrap();
163//! ```
164//! 
165//! The above is not too efficient because in case of `nonblocking`, it will return none immidiatly and
166//! in case of `blocking` it would block thread.
167//! 
168//! A `Epoll`, `Select`, `KQueue` can be used to poll timer more efficient. Or, for example, `AsyncFd` from 
169//! `tokio` can be used too. 
170 
171pub extern crate nix;
172pub extern crate bitflags;
173pub extern crate chrono;
174pub extern crate rand;
175
176/// All code which should be ported to the specific OS. Contains a system timer
177/// implementation and poll.
178pub mod timer_portable;
179
180/// Crates error handling.
181pub mod error;
182
183/// Common things.
184pub mod common;
185
186
187/// A base implementation of the sorted timer timeout queue.
188pub mod deque_timeout;
189
190
191//pub mod periodic_timeout;
192
193#[cfg(test)]
194mod tests;
195
196// deque
197pub use deque_timeout::{OrderedTimerDeque, OrderdTimerDequeOnce, OrderdTimerDequePeriodic};
198
199pub use deque_timeout::timer_consumer::TimerDequeueConsumer;
200pub use deque_timeout::timer_signal::{TimerDequeueSignal, TimerDequeueSignalTicket};
201pub use deque_timeout::timer_tickets::{TimerDequeueTicketIssuer, TimerDequeueTicket};
202
203pub use timer_portable::{TimerPoll, TimerReadRes, FdTimerCom, AbsoluteTime, RelativeTime};
204
205pub use common::TimerDequeueId;