timer_deque_rs/timer_portable/unix/
mod.rs1
2
3#[cfg(
4 any(
5 target_os = "freebsd",
6 target_os = "dragonfly",
7 target_os = "netbsd",
8 target_os = "openbsd",
9 target_os = "macos",
10 )
11 )
12]
13pub mod bsd;
14
15#[cfg(target_os = "linux")]
16pub mod linux;
17
18use std::{fmt, io};
19pub use std::os::fd::{AsFd, AsRawFd, BorrowedFd, RawFd};
20
21pub use nix::libc::{self, ECANCELED, EWOULDBLOCK};
22
23#[cfg(target_os = "linux")]
25pub use linux::timer_poll::TimerEventWatch;
26
27
28#[cfg(
29 any(
30 target_os = "freebsd",
31 target_os = "dragonfly",
32 target_os = "netbsd",
33 target_os = "openbsd",
34 target_os = "macos",
35 )
36)]
37pub use bsd::TimerEventWatch;
38
39
40#[cfg(target_os = "linux")]
42pub use linux::timer_fd_linux::TimerFdInternal;
43
44use crate::{AbsoluteTime, RelativeTime, TimerFd, TimerReadRes, timer_portable::{TimerExpMode, TimerId, timer::ModeTimeType}};
45
46#[cfg(
47 all(
48 any(
49 target_os = "freebsd",
50 target_os = "dragonfly",
51 target_os = "netbsd",
52 target_os = "openbsd",
53 target_os = "macos",
54 ),
55 feature = "bsd_use_timerfd"
56 )
57)]
58pub use bsd::timer_fd_bsd::TimerFdInternal;
59
60#[cfg(
61 all(
62 any(
63 target_os = "freebsd",
64 target_os = "dragonfly",
65 target_os = "netbsd",
66 target_os = "openbsd",
67 target_os = "macos",
68 ),
69 not(feature = "bsd_use_timerfd")
70 )
71)]
72pub use bsd::timer_kqueue_fd_bsd::TimerFdInternal;
73
74
75use bitflags::bitflags;
76
77#[allow(non_camel_case_types)]
79#[repr(i32)]
80#[derive(Debug)]
81pub enum TimerType
82{
83 CLOCK_REALTIME = libc::CLOCK_REALTIME,
85
86 CLOCK_MONOTONIC = libc::CLOCK_MONOTONIC,
91
92
93 #[cfg(target_os = "linux")]
101 CLOCK_BOOTTIME = libc::CLOCK_BOOTTIME,
102
103 #[cfg(target_os = "linux")]
107 CLOCK_REALTIME_ALARM = libc::CLOCK_REALTIME_ALARM,
108
109 #[cfg(target_os = "linux")]
113 CLOCK_BOOTTIME_ALARM = libc::CLOCK_BOOTTIME_ALARM,
114}
115
116impl From<TimerType> for libc::clockid_t
117{
118 fn from(value: TimerType) -> Self
119 {
120 return value as libc::clockid_t;
121 }
122}
123
124
125bitflags! {
126 #[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
128 pub struct TimerFlags: i32
129 {
130 const TFD_NONBLOCK = libc::TFD_NONBLOCK;
135
136 const TFD_CLOEXEC = libc::TFD_CLOEXEC;
140 }
141}
142
143
144bitflags! {
145 #[derive(Default, Debug, Eq, PartialEq, Clone, Copy)]
147 pub struct TimerSetTimeFlags: i32
148 {
149 const TFD_TIMER_ABSTIME = libc::TFD_TIMER_ABSTIME;
153
154 const TFD_TIMER_CANCEL_ON_SET = libc::TFD_TIMER_CANCEL_ON_SET;
162 }
163}
164
165impl From<RawFd> for TimerId
167{
168 fn from(value: RawFd) -> Self
169 {
170 return Self(value as usize);
171 }
172}
173
174impl From<u64> for TimerId
175{
176 fn from(value: u64) -> Self
177 {
178 return Self(value as usize);
179 }
180}
181
182impl PartialEq<RawFd> for TimerId
193{
194 fn eq(&self, other: &RawFd) -> bool
195 {
196 return self.0 == *other as usize;
197 }
198}
199
200pub trait UnixFd: AsFd + AsRawFd + PartialEq<RawFd> {}
203
204impl UnixFd for TimerFd {}
208
209impl PartialEq<RawFd> for TimerFd
210{
211 fn eq(&self, other: &RawFd) -> bool
212 {
213 return self.as_raw_fd() == *other;
214 }
215}
216
217impl AsFd for TimerFd
218{
219 fn as_fd(&self) -> BorrowedFd<'_>
220 {
221 return self.get_timer().as_fd();
222 }
223}
224
225impl AsRawFd for TimerFd
226{
227 fn as_raw_fd(&self) -> RawFd
228 {
229 return self.get_timer().as_raw_fd();
230 }
231}
232
233pub use nix::libc::{itimerspec, timespec};
236
237impl<TIMERTYPE: ModeTimeType> From<itimerspec> for TimerExpMode<TIMERTYPE>
239{
240 fn from(value: itimerspec) -> Self
241 {
242 if value.it_interval.tv_sec == 0 && value.it_interval.tv_nsec == 0 &&
243 value.it_value.tv_sec == 0 && value.it_value.tv_nsec == 0
244 {
245 return Self::None;
247 }
248 else if value.it_interval.tv_sec == 0 && value.it_interval.tv_nsec == 0
249 {
250 return
252 Self::OneShot
253 {
254 timeout: TIMERTYPE::from(value.it_value)
255 };
256 }
257 else if value.it_interval.tv_sec == value.it_value.tv_sec &&
258 value.it_interval.tv_nsec == value.it_value.tv_nsec
259 {
260 return
262 Self::Interval
263 {
264 interv_tm: TIMERTYPE::from(value.it_interval)
265 };
266 }
267 else
268 {
269 return
271 Self::IntervalDelayed
272 {
273 delay_tm: TIMERTYPE::from(value.it_value),
274 interv_tm: TIMERTYPE::from(value.it_interval)
275 };
276 }
277 }
278}
279
280impl From<timespec> for RelativeTime
281{
282 fn from(time_spec: timespec) -> Self
283 {
284 return
285 Self::new_time(time_spec.tv_sec, time_spec.tv_nsec);
286 }
287}
288
289
290impl From<timespec> for AbsoluteTime
291{
292 fn from(time_spec: timespec) -> Self
293 {
294 return
295 unsafe
296 {
297 Self::new_time_unchecked(time_spec.tv_sec, time_spec.tv_nsec)
298 };
299 }
300}
301
302impl<T: Sized + fmt::Debug + fmt::Display + Clone + Eq + PartialEq> From<io::Error> for TimerReadRes<T>
303{
304 fn from(value: io::Error) -> Self
305 {
306 if let Some(errn) = value.raw_os_error()
307 {
308 if errn == ECANCELED
309 {
310 return Self::Cancelled;
311 }
312 else if errn == EWOULDBLOCK
313 {
314 return Self::WouldBlock;
315 }
316 }
317
318 return Self::Cancelled;
319 }
320}
321
322impl<TIMERTYPE: ModeTimeType> From<TimerExpMode<TIMERTYPE>> for itimerspec
323{
324 fn from(value: TimerExpMode<TIMERTYPE>) -> Self
325 {
326 return (&value).into();
327 }
328}
329
330impl<TIMERTYPE: ModeTimeType> From<&TimerExpMode<TIMERTYPE>> for itimerspec
333{
334 fn from(value: &TimerExpMode<TIMERTYPE>) -> Self
335 {
336 match value
337 {
338 TimerExpMode::None =>
339 return
340 itimerspec
341 {
342 it_interval: timespec
343 {
344 tv_sec: 0,
345 tv_nsec: 0,
346 },
347 it_value: timespec
348 {
349 tv_sec: 0,
350 tv_nsec: 0,
351 },
352 },
353 TimerExpMode::OneShot{ timeout} =>
354 return
355 itimerspec
356 {
357 it_interval: timespec
358 {
359 tv_sec: 0,
360 tv_nsec: 0,
361 },
362 it_value: timespec
363 {
364 tv_sec: timeout.get_sec(),
365 tv_nsec: timeout.get_nsec(),
366 },
367 },
368 TimerExpMode::IntervalDelayed{ delay_tm, interv_tm } =>
369 return
370 itimerspec
371 {
372 it_interval: timespec
373 {
374 tv_sec: interv_tm.get_sec(),
375 tv_nsec: interv_tm.get_nsec(),
376 },
377 it_value: timespec
378 {
379 tv_sec: delay_tm.get_sec(),
380 tv_nsec: delay_tm.get_nsec(),
381 },
382 },
383 TimerExpMode::Interval{ interv_tm } =>
384 return
385 itimerspec
386 {
387 it_interval: timespec
388 {
389 tv_sec: interv_tm.get_sec(),
390 tv_nsec: interv_tm.get_nsec(),
391 },
392 it_value: timespec
393 {
394 tv_sec: interv_tm.get_sec(),
395 tv_nsec: interv_tm.get_nsec(),
396 },
397 }
398 }
399 }
400}
401
402
403
404
405
406#[cfg(all(target_family = "unix", feature = "enable_mio_compat"))]
407pub mod mio_compat
408{
409 use std::{io, os::fd::{AsRawFd, RawFd}};
410
411 use mio::{Token, unix::SourceFd};
412
413 use crate::timer_portable::timer::TimerFdMioCompat;
414
415 use super::TimerFd;
416
417 impl mio::event::Source for TimerFd
418 {
419 fn register(
420 &mut self,
421 registry: &mio::Registry,
422 token: mio::Token,
423 interests: mio::Interest,
424 ) -> io::Result<()>
425 {
426 return
427 SourceFd(&self.as_raw_fd()).register(registry, token, interests);
428 }
429
430 fn reregister(
431 &mut self,
432 registry: &mio::Registry,
433 token: mio::Token,
434 interests: mio::Interest,
435 ) -> io::Result<()>
436 {
437 return
438 SourceFd(&self.as_raw_fd()).reregister(registry, token, interests);
439 }
440
441 fn deregister(&mut self, registry: &mio::Registry) -> io::Result<()>
442 {
443 return
444 SourceFd(&self.as_raw_fd()).deregister(registry)
445 }
446 }
447
448
449 impl PartialEq<Token> for TimerFd
450 {
451 fn eq(&self, other: &Token) -> bool
452 {
453 return self.as_raw_fd() == other.0 as RawFd;
454 }
455 }
456
457 impl TimerFdMioCompat for TimerFd
458 {
459 fn get_token(&self) -> Token
460 {
461 return Token(self.as_raw_fd() as usize);
462 }
463 }
464}