timer_deque_rs/timer_portable/
timer.rs

1/*-
2 * timer-deque-rs - a Rust crate which provides timer and timer queues based on target OS
3 *  functionality.
4 * 
5 * Copyright (C) 2025 Aleksandr Morozov alex@nixd.org
6 *  4neko.org alex@4neko.org
7 * 
8 * The timer-rs crate can be redistributed and/or modified
9 * under the terms of either of the following licenses:
10 *
11 *   1. the Mozilla Public License Version 2.0 (the “MPL”) OR
12 *                     
13 *   2. The MIT License (MIT)
14 *                     
15 *   3. EUROPEAN UNION PUBLIC LICENCE v. 1.2 EUPL © the European Union 2007, 2016
16 */
17
18use std::{borrow::Cow, cmp::Ordering, fmt, io::{self}, ops::{self, Deref}, os::fd::{AsFd, AsRawFd, BorrowedFd, RawFd}, sync::Arc, task::Poll, time::Duration};
19
20use chrono::{DateTime, TimeZone};
21use nix::libc::{self, ECANCELED, EWOULDBLOCK};
22use bitflags::bitflags;
23
24
25use crate::{common, timer_portable::portable_error::TimerPortResult};
26
27#[cfg(target_os = "linux")]
28pub use super::linux::timer_fd_linux::TimerFdInternal;
29
30#[cfg(
31    all(
32        any(
33            target_os = "freebsd",
34            target_os = "dragonfly",
35            target_os = "netbsd",
36            target_os = "openbsd",
37            target_os = "macos",
38        ),
39        feature = "bsd_use_timerfd"
40    )
41)]
42pub use super::bsd::timer_fd_bsd::TimerFdInternal;
43
44#[cfg(
45    all(
46        any(
47            target_os = "freebsd",
48            target_os = "dragonfly",
49            target_os = "netbsd",
50            target_os = "openbsd",
51            target_os = "macos",
52        ),
53        not(feature = "bsd_use_timerfd")
54    )
55)]
56pub use super::bsd::timer_kqueue_fd_bsd::TimerFdInternal;
57
58
59/// A timer type
60#[allow(non_camel_case_types)]
61#[repr(i32)]
62#[derive(Debug)]
63pub enum TimerType
64{
65    /// A settable system-wide real-time clock.
66    CLOCK_REALTIME = libc::CLOCK_REALTIME,
67
68    /// A nonsettable monotonically increasing clock that measures  time
69    /// from some unspecified point in the past that does not change af‐
70    /// ter system startup.
71
72    CLOCK_MONOTONIC = libc::CLOCK_MONOTONIC,
73
74    
75    /// Like CLOCK_MONOTONIC, this is a monotonically increasing  clock.
76    /// However,  whereas the CLOCK_MONOTONIC clock does not measure the
77    /// time while a system is suspended, the CLOCK_BOOTTIME clock  does
78    /// include  the time during which the system is suspended.  This is
79    /// useful  for  applications  that  need   to   be   suspend-aware.
80    /// CLOCK_REALTIME is not suitable for such applications, since that
81    /// clock is affected by discontinuous changes to the system clock.
82    #[cfg(target_os = "linux")]
83    CLOCK_BOOTTIME = libc::CLOCK_BOOTTIME,
84
85    /// This clock is like CLOCK_REALTIME, but will wake the  system  if
86    /// it  is suspended.  The caller must have the CAP_WAKE_ALARM capa‐
87    /// bility in order to set a timer against this clock.
88    #[cfg(target_os = "linux")]
89    CLOCK_REALTIME_ALARM = libc::CLOCK_REALTIME_ALARM,
90
91    /// This clock is like CLOCK_BOOTTIME, but will wake the  system  if
92    /// it  is suspended.  The caller must have the CAP_WAKE_ALARM capa‐
93    /// bility in order to set a timer against this clock.
94    #[cfg(target_os = "linux")]
95    CLOCK_BOOTTIME_ALARM = libc::CLOCK_BOOTTIME_ALARM,
96}
97
98/*
99impl Into<libc::clockid_t> for TimerType 
100{
101    fn into(self) -> libc::clockid_t
102    {
103        match self
104        {
105            Self::CLOCK_REALTIME        => return ,
106            Self::CLOCK_MONOTONIC       => return ,
107            #[cfg(target_os = "linux")]
108            Self::CLOCK_BOOTTIME        => return libc::CLOCK_BOOTTIME,
109            #[cfg(target_os = "linux")]
110            Self::CLOCK_REALTIME_ALARM  => return libc::CLOCK_REALTIME_ALARM,
111            #[cfg(target_os = "linux")]
112            Self::CLOCK_BOOTTIME_ALARM  => return libc::CLOCK_BOOTTIME_ALARM,
113            #[cfg(any(
114                target_os = "freebsd",
115                target_os = "dragonfly",
116                target_os = "netbsd",
117                target_os = "openbsd",
118                target_os = "macos",
119            ))]
120            _ => return libc::CLOCK_REALTIME,
121        }
122    }
123}*/
124
125impl From<TimerType> for libc::clockid_t 
126{
127    fn from(value: TimerType) -> Self 
128    {
129        return value as libc::clockid_t;
130    }
131}
132
133
134bitflags! {     
135    /// Flags controling the type of the timer type.  
136    #[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] 
137    pub struct TimerFlags: i32  
138    {     
139        /// Set the O_NONBLOCK file status flag on the open file  de‐
140        /// scription  (see  open(2)) referred to by the new file de‐
141        /// scriptor.  Using this flag saves extra calls to  fcntl(2)
142        /// to achieve the same result.
143        const TFD_NONBLOCK = libc::TFD_NONBLOCK;
144
145        /// Set  the  close-on-exec (FD_CLOEXEC) flag on the new file
146        /// descriptor.  See the description of the O_CLOEXEC flag in
147        /// open(2) for reasons why this may be useful.
148        const TFD_CLOEXEC = libc::TFD_CLOEXEC;
149    }
150}
151
152
153bitflags! {     
154    /// A bit mask that can include the values.
155    #[derive(Default, Debug, Eq, PartialEq, Clone, Copy)] 
156    pub struct TimerSetTimeFlags: i32  
157    {     
158        /// > Interpret  new_value.it_value as an absolute value on the timer's
159        /// > clock.  The timer will expire when the value of the timer's clock
160        /// > reaches the value specified in new_value.it_value.
161        const TFD_TIMER_ABSTIME = libc::TFD_TIMER_ABSTIME;
162
163        /// > If this flag is specified along with  TFD_TIMER_ABSTIME  and  the
164        /// > clock  for  this timer is CLOCK_REALTIME or CLOCK_REALTIME_ALARM,
165        /// > then mark this timer as cancelable if the real-time clock  under‐
166        /// > goes  a  discontinuous change (settimeofday(2), clock_settime(2),
167        /// > or similar).  When  such  changes  occur,  a  current  or  future
168        /// > read(2)  from  the file descriptor will fail with the error 
169        /// > ECANCELED.
170        const TFD_TIMER_CANCEL_ON_SET = libc::TFD_TIMER_CANCEL_ON_SET;
171    }
172}
173
174
175/// A super trait which defines a standart interface for the different time types i.e
176/// 
177/// - [RelativeTime] a relative time to the system's clock.
178/// 
179/// - [AbsoluteTime] an absolute time to the systmem's clock.
180/// 
181/// This is an internal trait and should not be exposed to the outside of the crate.
182/// 
183/// ## Traits
184/// 
185/// * [From<timespec>] - creates new instance from the two components: seconds and 
186///     subnanoseconds of the seconds.
187/// 
188/// * [PartialEq] - comares the instances
189/// 
190/// * [PartialOrd] - ordering for sorting which compares both sec and nsec
191/// 
192/// * [fmt::Display] - displays the content in human readable format.
193pub trait ModeTimeType: 
194    Eq + PartialEq + Ord + PartialOrd + fmt::Display + fmt::Debug + Clone + Copy +
195    From<timespec> + fmt::Display
196{
197    /// Returns the seconds without the nanoseconds fraction.
198    fn get_sec(&self) -> i64;
199
200    /// Returns the nanoseconds fraction from seconds, not a full time in nanoseconds.
201    fn get_nsec(&self) -> i64;
202
203    /// Verifies that the timer is not set to zero. For the [RelativeTime] it always returns true.
204    fn is_value_valid(&self) -> bool;
205
206    /// Returns the [TimerSetTimeFlags] which are autoinitialized for both types. This flags
207    /// should be passed to timer.
208    fn get_flags() -> TimerSetTimeFlags;
209}
210
211/// A `relative` time i.e time which is not binded to the system's clock.
212/// 
213/// ## Implementations
214/// 
215/// ```ignore
216///     RelativeTime::from(Duration::from_sec(1));
217/// ```
218/// 
219/// ```ignore
220///     RelativeTime::from(10);
221/// ```
222/// 
223/// ```ignore
224///     RelativeTime::from((10, 46000));
225/// ```
226/// 
227/// ```ignore
228///     RelativeTime::new_time(10, 46000);
229/// ```
230#[derive(Debug, PartialEq, Eq, Clone, Copy)]
231pub struct RelativeTime
232{
233    /// Seconds
234    time_sec: i64,
235
236    /// A fraction of ns from second
237    time_nsec: i64,
238}
239
240/// Converts the [Duration] to [RelativeTime] taking the `subsec_nanos`
241/// for the `time_nsec`.
242impl From<Duration> for RelativeTime
243{
244    fn from(value: Duration) -> Self 
245    {
246        return Self
247        {
248            time_sec: 
249                value.as_secs() as i64,
250            time_nsec: 
251                value.subsec_nanos() as i64,
252        };
253    }
254}
255
256/// Converts the [i64] (seconds) to [RelativeTime] ignoring
257/// the `subsec_nanos` fraction and setting it to zero.
258impl From<i64> for RelativeTime
259{
260    fn from(value: i64) -> Self 
261    {
262        return 
263            Self
264            {
265                time_sec: 
266                    value,
267                time_nsec: 
268                    0
269            };
270    }
271}
272
273/// Converts the [u64] (seconds) to [RelativeTime] ignoring
274/// the `subsec_nanos` fraction and setting it to zero.
275impl From<u64> for RelativeTime
276{
277    fn from(value: u64) -> Self 
278    {
279        return 
280            Self
281            {
282                time_sec: 
283                    value as i64,
284                time_nsec: 
285                    0
286            };
287    }
288}
289
290/// Converts the tuple (i64, i64) (seconds, nsec) to [RelativeTime] ignoring
291/// the `subsec_nanos` fraction and setting it to zero.
292impl From<(i64, i64)> for RelativeTime
293{
294    fn from(value: (i64, i64)) -> Self 
295    {
296        return 
297            Self
298            {
299                time_sec: 
300                    value.0,
301                time_nsec: 
302                    value.1
303            };
304    }
305}
306
307/// Converts the [u128] (MSB:seconds|LSB:nanosec) to [RelativeTime] by 
308/// separationg MSB seconds from nanoseconds
309impl From<u128> for RelativeTime
310{
311    fn from(value: u128) -> Self 
312    {
313        // this is faster, but unsafe 
314        //return unsafe { std::mem::transmute(value) };
315
316        return 
317            Self
318            {
319                time_sec: 
320                    ((value & 0xFFFF_FFFF_FFFF_FFFF_0000_0000_0000_0000) >> 64) as i64,
321                time_nsec: 
322                    (value & 0x0000_0000_0000_0000_FFFF_FFFF_FFFF_FFFF) as i64
323            };
324    }
325}
326
327
328impl From<RelativeTime> for Duration
329{
330    fn from(value: RelativeTime) -> Self 
331    {
332        return Duration::new(value.time_sec as u64, value.time_nsec as u32);
333    }
334}
335
336impl Ord for RelativeTime
337{
338    fn cmp(&self, other: &Self) -> Ordering 
339    {
340        return 
341            self
342                .time_sec
343                .cmp(&other.time_sec)
344                .then(
345                    self
346                        .time_nsec
347                        .cmp(&other.time_nsec)
348                );
349    }
350}
351
352impl PartialOrd for RelativeTime
353{
354    fn partial_cmp(&self, other: &Self) -> Option<Ordering> 
355    {
356        return Some(self.cmp(other));
357    }
358}
359
360impl fmt::Display for RelativeTime
361{
362    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result 
363    {
364        write!(f, "[relative] sec: {}, nsec: {}", self.time_sec, self.time_nsec)
365    }
366}
367
368impl From<timespec> for RelativeTime
369{
370    fn from(time_spec: timespec) -> Self 
371    {
372        return   
373            Self::new_time(time_spec.tv_sec, time_spec.tv_nsec);
374    }
375}
376
377impl ModeTimeType for RelativeTime
378{
379    fn get_sec(&self) -> i64 
380    {
381        return self.time_sec;
382    }
383    
384    fn get_nsec(&self) -> i64 
385    {
386        return self.time_nsec;
387    }
388
389    fn is_value_valid(&self) -> bool 
390    {
391        return true;    
392    }
393
394    fn get_flags() -> TimerSetTimeFlags
395    {
396        return TimerSetTimeFlags::empty();
397    }
398}
399
400impl RelativeTime
401{
402    /// max nanoseconds
403    pub const MAX_NS: i64 = 1_000_000_000;
404
405    /// Creates new instance for relative time accepting the user input.
406    /// 
407    /// Automatically corrects the `time_nsec` value if it is larger than
408    /// 999_999_999ns.
409    /// 
410    /// # Arguments
411    /// 
412    /// `time_sec` - [i64] a seconds in relative notation.
413    /// 
414    /// `time_nsec` - [i64] nanoseconds of relative seconds value. Should not be 
415    ///     larger than 999_999_999 which is defined by const [Self::MAX_NS]. In
416    ///     case if it is larger, the `nsec` will be rounded and an extra secons
417    ///     will be added.
418    pub 
419    fn new_time(time_sec: i64, time_nsec: i64) -> Self
420    {
421        let extra_sec = time_nsec / Self::MAX_NS;
422        let nsec_new = time_nsec % Self::MAX_NS;
423
424        return 
425            Self
426            { 
427                time_nsec: nsec_new, 
428                time_sec: time_sec + extra_sec,
429            };
430    }
431
432    pub 
433    fn is_zero(&self) -> bool
434    {
435        return self.time_nsec == 0 && self.time_sec == 0;
436    } 
437}
438
439/// An `absolute` time which are binded to the system's clock
440/// and never be zero except when timer is reset.
441/// 
442/// ## Implementations
443/// 
444/// ```ignore
445///     AbsoluteTime::from(LocalTime::now());
446/// ```
447/// 
448/// ```ignore
449///     AbsoluteTime::from(Duration::from_sec(1));
450/// ```
451/// 
452/// ```ignore
453///     AbsoluteTime::from(10);
454/// ```
455/// 
456/// ```ignore
457///     AbsoluteTime::from((10, 46000));
458/// ```
459/// 
460/// ```ignore
461///     AbsoluteTime::new_time(10, 46000);
462/// ```
463#[derive(Debug, PartialEq, Eq, Clone, Copy)]
464pub struct AbsoluteTime
465{
466    /// A full seconds.
467    time_sec: i64,
468
469    /// A fraction (subset) of nanoseconds from the second.
470    time_nsec: i64,
471}
472
473/// Convers the `chrono` [DateTime<TZ>] into the [AbsoluteTime] using 
474/// the `TZ` [TimeZone]  taking the `ns` fraction of a second (subsec_nano) 
475/// using `timestamp_subsec_nanos` function.
476impl<TZ: TimeZone> From<DateTime<TZ>> for AbsoluteTime
477{
478    fn from(value: DateTime<TZ>) -> Self 
479    {
480        return 
481            Self
482            {
483                time_sec: 
484                    value.timestamp(), 
485                time_nsec: 
486                    value.timestamp_subsec_nanos() as i64,
487            };
488    }
489}
490
491/// Converts the [Duration] to [AbsoluteTime] taking the `subsec_nanos`
492/// for the `time_nsec`.
493impl From<Duration> for AbsoluteTime
494{
495    fn from(value: Duration) -> Self 
496    {
497        return 
498            Self
499            {
500                time_sec: 
501                    value.as_secs() as i64,
502                time_nsec: 
503                    value.subsec_nanos() as i64,
504            };
505    }
506}
507
508/// Converts the [i64] (seconds) to [AbsoluteTime] ignoring
509/// the `subsec_nanos` fraction and setting it to zero.
510impl From<i64> for AbsoluteTime
511{
512    fn from(value: i64) -> Self 
513    {
514        return 
515            Self
516            {
517                time_sec: 
518                    value,
519                time_nsec: 
520                    0
521            };
522    }
523}
524
525/// Converts the [u64] (seconds) to [AbsoluteTime] ignoring
526/// the `subsec_nanos` fraction and setting it to zero.
527impl From<u64> for AbsoluteTime
528{
529    fn from(value: u64) -> Self 
530    {
531        return 
532            Self
533            {
534                time_sec: 
535                    value as i64,
536                time_nsec: 
537                    0
538            };
539    }
540}
541
542/// Converts the tuple (i64, i64) (seconds, nsec) to [AbsoluteTime] ignoring
543/// the `subsec_nanos` fraction and setting it to zero.
544impl From<(i64, i64)> for AbsoluteTime
545{
546    fn from(value: (i64, i64)) -> Self 
547    {
548        return 
549            Self
550            {
551                time_sec: 
552                    value.0,
553                time_nsec: 
554                    value.1
555            };
556    }
557}
558
559/// Converts the [u128] (MSB:seconds|LSB:nanosec) to [AbsoluteTime] by 
560/// separationg MSB seconds from nanoseconds
561impl From<u128> for AbsoluteTime
562{
563    fn from(value: u128) -> Self 
564    {
565        // this is faster, but unsafe 
566        //return unsafe { std::mem::transmute(value) };
567
568        return 
569            Self
570            {
571                time_sec: 
572                    ((value & 0xFFFF_FFFF_FFFF_FFFF_0000_0000_0000_0000) >> 64) as i64,
573                time_nsec: 
574                    (value & 0x0000_0000_0000_0000_FFFF_FFFF_FFFF_FFFF) as i64
575            };
576    }
577}
578
579impl From<AbsoluteTime> for Duration
580{
581    fn from(value: AbsoluteTime) -> Self 
582    {
583        return Duration::new(value.time_sec as u64, value.time_nsec as u32);
584    }
585}
586
587impl Ord for AbsoluteTime
588{
589    fn cmp(&self, other: &Self) -> Ordering 
590    {
591        return 
592            self
593                .time_sec
594                .cmp(&other.time_sec)
595                .then(
596                    self
597                        .time_nsec
598                        .cmp(&other.time_nsec)
599                );
600    }
601}
602
603impl PartialOrd for AbsoluteTime
604{
605    fn partial_cmp(&self, other: &Self) -> Option<Ordering> 
606    {
607        return Some(self.cmp(other));
608    }
609}
610
611impl ops::AddAssign<Duration> for AbsoluteTime
612{
613    fn add_assign(&mut self, rhs: Duration) 
614    {
615        self.time_nsec += rhs.subsec_nanos() as i64;
616        let add_sec = self.time_nsec / Self::MAX_NS;
617
618        if add_sec > 0
619        {
620            self.time_nsec %=  Self::MAX_NS;
621        }
622        
623        self.time_sec += rhs.as_secs() as i64 + add_sec;
624    }
625}
626
627impl ops::AddAssign<RelativeTime> for AbsoluteTime
628{
629    fn add_assign(&mut self, rhs: RelativeTime) 
630    {
631        self.time_nsec += rhs.time_nsec;
632        let add_sec = self.time_nsec / Self::MAX_NS;
633
634        if add_sec > 0
635        {
636            self.time_nsec %=  Self::MAX_NS;
637        }
638        
639        self.time_sec += rhs.time_sec + add_sec;
640    }
641}
642
643impl ops::Add<Duration> for AbsoluteTime
644{
645    type Output = AbsoluteTime;
646
647    fn add(mut self, rhs: Duration) -> Self::Output 
648    {
649        self += rhs;
650
651        return self;
652    }
653}
654
655impl ops::Add<RelativeTime> for AbsoluteTime
656{
657    type Output = AbsoluteTime;
658
659    fn add(mut self, rhs: RelativeTime) -> Self::Output 
660    {
661        self += rhs;
662
663        return self;
664    }
665}
666
667impl ops::SubAssign<Duration> for AbsoluteTime
668{
669    fn sub_assign(&mut self, rhs: Duration) 
670    {
671        let mut sec = rhs.as_secs() as i64;
672        let mut nsec = self.time_nsec - rhs.subsec_nanos() as i64;
673
674        if nsec < 0
675        {
676            sec += 1;
677
678            nsec = Self::MAX_NS + nsec;
679        }
680        
681        self.time_nsec = nsec;
682        self.time_sec -= sec;
683
684        return;
685    }
686}
687
688impl ops::SubAssign<RelativeTime> for AbsoluteTime
689{
690    fn sub_assign(&mut self, mut rhs: RelativeTime) 
691    {
692
693        let mut nsec = self.time_nsec - rhs.time_nsec;
694
695        if nsec < 0
696        {
697            rhs.time_sec += 1;
698
699            nsec = Self::MAX_NS + nsec;
700        }
701        
702        self.time_nsec = nsec;
703        self.time_sec -= rhs.time_sec;
704
705        return;
706    }
707}
708
709impl ops::Sub<Duration> for AbsoluteTime
710{
711    type Output = AbsoluteTime;
712
713    fn sub(mut self, rhs: Duration) -> Self::Output 
714    {
715        self -= rhs;
716
717        return self;
718    }
719}
720
721impl ops::Sub<RelativeTime> for AbsoluteTime
722{
723    type Output = AbsoluteTime;
724
725    fn sub(mut self, rhs: RelativeTime) -> Self::Output 
726    {
727        self -= rhs;
728
729        return self;
730    }
731}
732
733impl ops::SubAssign for AbsoluteTime
734{
735    fn sub_assign(&mut self, mut rhs: Self) 
736    {
737
738        let mut nsec = self.time_nsec - rhs.time_nsec;
739
740        if nsec < 0
741        {
742            rhs.time_sec += 1;
743
744            nsec = Self::MAX_NS + nsec;
745        }
746        
747        self.time_nsec = nsec;
748        self.time_sec -= rhs.time_sec;
749
750        return;
751    }
752}
753
754impl ops::Sub for AbsoluteTime
755{
756    type Output = AbsoluteTime;
757
758    fn sub(mut self, rhs: Self) -> Self::Output 
759    {
760        self -= rhs;
761
762        return self;
763    }
764}
765
766
767impl fmt::Display for AbsoluteTime
768{
769    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result 
770    {
771        write!(f, "[absolute] {}.{:09}sec", self.time_sec, self.time_nsec)
772    }
773}
774
775impl From<timespec> for AbsoluteTime
776{
777    fn from(time_spec: timespec) -> Self 
778    {
779        return 
780            unsafe 
781            { 
782                Self::new_time_unchecked(time_spec.tv_sec, time_spec.tv_nsec) 
783            };
784    }
785}
786
787impl ModeTimeType for AbsoluteTime
788{
789    fn get_sec(&self) -> i64 
790    {
791        return self.time_sec;
792    }
793    
794    fn get_nsec(&self) -> i64 
795    {
796        return self.time_nsec;
797    }
798
799    fn is_value_valid(&self) -> bool 
800    {
801        return self.time_nsec != 0 || self.time_sec != 0;
802    }
803
804    fn get_flags() -> TimerSetTimeFlags
805    {
806        return TimerSetTimeFlags::TFD_TIMER_ABSTIME | TimerSetTimeFlags::TFD_TIMER_CANCEL_ON_SET;
807    }
808}
809
810impl AbsoluteTime
811{
812    /// max nanoseconds
813    pub const MAX_NS: i64 = 1_000_000_000;//999_999_999;
814}
815
816impl AbsoluteTime
817{
818    /// Creates an instance with the current local time.
819    pub 
820    fn now() -> Self
821    {
822        let value = common::get_current_timestamp();
823
824        return Self
825        {
826            time_sec: value.timestamp(), 
827            time_nsec: value.timestamp_subsec_nanos() as i64,
828        }
829    }
830
831    pub 
832    fn new_time(time_sec: i64, time_nsec: i64) -> Option<Self>
833    {
834        let tm = 
835            unsafe { Self::new_time_unchecked(time_sec, time_nsec) };
836
837        if tm.is_value_valid() == false
838        {
839            return None;
840        }
841
842        return Some(tm);
843    }
844
845    /// Creates new instance for absolute time accepting the user input.
846    /// 
847    /// Automatically corrects the `time_nsec` value if it is larger than
848    /// 999_999_999ns.
849    /// 
850    /// # Arguments
851    /// 
852    /// `time_sec` - [i64] a seconds in absolute notation.
853    /// 
854    /// `time_nsec` - [i64] nanoseconds of absolute seconds value. Should not be 
855    ///     larger than 999_999_999 which is defined by const [Self::MAX_NS]. In
856    ///     case if it is larger, the `nsec` will be rounded and an extra secons
857    ///     will be added.
858    /// 
859    /// # Returns 
860    /// 
861    /// An instance is returned. May panic on overflow.
862    pub unsafe 
863    fn new_time_unchecked(time_sec: i64, time_nsec: i64) -> Self
864    {
865        let extra_sec = time_nsec / Self::MAX_NS;
866        let nsec_new = time_nsec % Self::MAX_NS;
867
868        return 
869            Self
870            { 
871                time_nsec: nsec_new, 
872                time_sec: time_sec + extra_sec,
873            };
874    }
875
876    /// Compares only full seconds without nanoseconds fraction (subnano).
877    pub 
878    fn seconds_cmp(&self, other: &Self) -> Ordering
879    {
880        return self.time_sec.cmp(&other.time_sec);
881    }
882
883    pub 
884    fn add_sec(mut self, seconds: i64) -> Self
885    {
886        self.time_sec += seconds;
887
888        return self;
889    }
890
891    pub 
892    fn reset_nsec(mut self) -> Self
893    {
894        self.time_nsec = 0;
895
896        return self;
897    }
898}
899
900
901/// A timer expiry modes. Not every OS supports 
902/// every mode. Read comments for the OS specific
903/// timer. For the `nanoseconds` param the max value
904/// is 999_999_999 for most OSes.
905#[derive(Clone, Copy, Debug, PartialEq, Eq)]
906pub enum TimerExpMode<TIMERTYPE: ModeTimeType>
907{
908    /// Disarmed
909    None, 
910
911    /// A timer which is triggered once.
912    OneShot
913    {
914        timeout: TIMERTYPE
915    },
916    
917    /// Interval with the initial delay.
918    IntervalDelayed
919    {
920        /// First event delay.
921        delay_tm: TIMERTYPE,
922
923        /// Interval.
924        interv_tm: TIMERTYPE
925    },
926
927    /// Interval, with the first timeout event 
928    /// equal to interval values.
929    Interval
930    {
931        /// Interval seconds.
932        interv_tm: TIMERTYPE
933    },
934}
935
936
937impl ops::AddAssign<RelativeTime> for TimerExpMode<AbsoluteTime>
938{
939    fn add_assign(&mut self, rhs: RelativeTime) 
940    {
941        match self
942        {
943            TimerExpMode::None => 
944                return,
945            TimerExpMode::OneShot { timeout } => 
946            {
947                *timeout += rhs;
948                
949            },
950            TimerExpMode::IntervalDelayed { interv_tm, .. } => 
951            {
952                *interv_tm += rhs;
953            },
954            TimerExpMode::Interval { interv_tm } => 
955            {
956               *interv_tm += rhs;
957            },
958        }
959    }
960}
961
962
963impl ops::Add<RelativeTime> for TimerExpMode<AbsoluteTime>
964{
965    type Output = TimerExpMode<AbsoluteTime>;
966
967    fn add(mut self, rhs: RelativeTime) -> Self::Output 
968    {
969        self += rhs;
970
971        return self;
972    }
973}
974
975
976impl<TIMERTYPE: ModeTimeType> Ord for TimerExpMode<TIMERTYPE>
977{
978    fn cmp(&self, other: &Self) -> Ordering 
979    {
980        match (self, other)
981        {
982            (TimerExpMode::None, TimerExpMode::None) => 
983                return Ordering::Equal,
984            (TimerExpMode::OneShot{ timeout }, TimerExpMode::OneShot { timeout: timeout2 }) => 
985            { 
986                return timeout.cmp(timeout2);
987            },
988            (
989                TimerExpMode::IntervalDelayed{ delay_tm, interv_tm }, 
990                TimerExpMode::IntervalDelayed{ delay_tm: delay_tm2, interv_tm: interv_tm2 }
991            ) =>
992            {
993                return 
994                    delay_tm.cmp(delay_tm2)
995                        .then(interv_tm.cmp(interv_tm2));
996            },
997            (TimerExpMode::Interval { interv_tm }, TimerExpMode::Interval { interv_tm: interv_tm2 }) => 
998            {
999                return interv_tm.cmp(interv_tm2);
1000            },
1001            _ => 
1002                panic!("cannot compare different types {} and {}", self, other)
1003        }
1004    }
1005}
1006
1007impl<TIMERTYPE: ModeTimeType> PartialOrd for TimerExpMode<TIMERTYPE>
1008{
1009    fn partial_cmp(&self, other: &Self) -> Option<Ordering> 
1010    {
1011        return Some(self.cmp(other));
1012    }
1013}
1014
1015
1016
1017/// Implementations of the [TimerExpMode] for [AbsoluteTime].
1018impl TimerExpMode<AbsoluteTime>
1019{
1020    /// Checks value for the `set_time` function. To disarm timer 
1021    /// use `unset_time`.
1022    #[inline]
1023    fn is_valid_inner(&self) -> bool
1024    {
1025        match self
1026        {
1027            Self::None => 
1028                return false,
1029            Self::OneShot{ timeout} => 
1030                return timeout.is_value_valid(),
1031            Self::IntervalDelayed{ delay_tm, interv_tm } => 
1032                return delay_tm.is_value_valid() && interv_tm.is_value_valid(),
1033            Self::Interval{ interv_tm } => 
1034                return interv_tm.is_value_valid()
1035        }
1036    }
1037
1038    /// Construct the [TimerExpMode::OneShot] timer. For the `absolute` timer
1039    /// only this type is available. The [AbsoluteTime] should be provided which
1040    /// should be ahead of the OS'es timer.
1041    pub 
1042    fn new_oneshot(abs_time: impl Into<AbsoluteTime>) -> Self
1043    {
1044        return Self::OneShot { timeout: abs_time.into() };
1045    }
1046}
1047
1048
1049
1050/// Implementations of the [TimerExpMode] for [RelativeTime].
1051impl TimerExpMode<RelativeTime>
1052{
1053    /// Construct the [TimerExpMode::OneShot] timer. A [RelativeTime] should 
1054    /// be provided as argument. This type of timer is triggered only once.
1055    pub 
1056    fn new_oneshot(rel_time: impl Into<RelativeTime>) -> Self
1057    {
1058        return Self::OneShot { timeout: rel_time.into() };
1059    }
1060
1061    /// Constrcut the [TimerExpMode::Interval] timer. A [RelativeTime] should 
1062    /// be provided as agument which specifies the trigger interval.
1063    pub 
1064    fn new_interval(rel_time: impl Into<RelativeTime>) -> Self
1065    {
1066        return Self::Interval { interv_tm: rel_time.into() };
1067    }
1068
1069    /// Construct the [TimerExpMode::IntervalDelayed] timer. A two [RelativeTime] 
1070    /// arguments should be provided which would set the initial delay and further
1071    /// interval. The initial delay happens only once. Then the interval will be used.
1072    /// If `delay_time` and `intev_time` are same, acts as `new_interval`.
1073    pub 
1074    fn new_interval_with_init_delay(delay_time: impl Into<RelativeTime>, intev_time: impl Into<RelativeTime>) -> Self
1075    {
1076        return Self::IntervalDelayed { delay_tm: delay_time.into(), interv_tm: intev_time.into() };
1077    }
1078}
1079
1080impl<TIMERTYPE: ModeTimeType> TimerExpMode<TIMERTYPE>
1081{
1082    /// Disarms the timer.
1083    #[inline]
1084    pub 
1085    fn reset() -> Self
1086    {
1087        return Self::None;
1088    }
1089}
1090
1091impl<TIMERTYPE: ModeTimeType> fmt::Display for TimerExpMode<TIMERTYPE>
1092{
1093    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result 
1094    {
1095        match self
1096        {
1097            Self::None => 
1098                write!(f, "disarmed"),
1099            Self::OneShot{ timeout } => 
1100                write!(f, "oneshot {}", timeout),
1101            Self::IntervalDelayed
1102                { delay_tm, interv_tm } => 
1103                write!(f, "interval {} with delay {}", interv_tm, delay_tm),
1104            Self::Interval{ interv_tm } => 
1105                write!(f, "interval {}", interv_tm),
1106        }
1107    }
1108}
1109
1110
1111
1112/*
1113#[cfg(target_os = "macos")]
1114#[repr(C)]
1115pub struct timespec 
1116{
1117    pub tv_sec: libc::time_t,
1118    pub tv_nsec: libc::c_long,
1119}
1120#[cfg(target_os = "macos")]
1121#[repr(C)]
1122pub struct itimerspec 
1123{
1124    pub it_interval: timespec,
1125    pub it_value: timespec,
1126}
1127    */
1128
1129/// A timer FD read operation result.
1130#[derive(Debug, Clone, PartialEq, Eq)]
1131pub enum TimerReadRes<T: Sized + fmt::Debug + fmt::Display + Clone + Eq + PartialEq>
1132{
1133    /// Read successfull.
1134    Ok(T),
1135
1136    /// TFD_TIMER_ABSTIME 
1137    /// > Marks this timer as cancelable if the real-time clock  under‐
1138    /// > goes  a  discontinuous change (settimeofday(2), clock_settime(2),
1139    /// > or similar).  When  such  changes  occur,  a  current  or  future
1140    /// > read(2)  from  the file descriptor will fail with the error 
1141    /// > ECANCELED.
1142    Cancelled,
1143
1144    /// EAGAIN
1145    /// If FD is nonblocking then this will be returned.
1146    WouldBlock,
1147}
1148
1149impl TimerReadRes<u64>
1150{
1151    pub 
1152    fn ok() -> Self
1153    {
1154        return Self::Ok(1);
1155    }
1156}
1157
1158impl<T: Sized + fmt::Debug + fmt::Display + Clone + Eq + PartialEq> From<io::Error> for TimerReadRes<T>
1159{
1160    fn from(value: io::Error) -> Self 
1161    {
1162        if let Some(errn) = value.raw_os_error()
1163        {
1164            if errn == ECANCELED
1165            {
1166                return Self::Cancelled;
1167            }
1168            else if errn == EWOULDBLOCK
1169            {
1170                return Self::WouldBlock;
1171            }
1172        }
1173
1174        return Self::Cancelled;
1175    }
1176}
1177
1178impl<T: Sized + fmt::Debug + fmt::Display + Clone + Eq + PartialEq> fmt::Display for TimerReadRes<T>
1179{
1180    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result 
1181    {
1182        match self
1183        {
1184            Self::Ok(ovfl) => 
1185                write!(f, "OK(overflows:{})", ovfl),
1186            Self::Cancelled => 
1187                write!(f, "CANCELLED"),
1188            Self::WouldBlock => 
1189                write!(f, "WOULDBLOCK"),
1190        }
1191    }
1192}
1193
1194impl<T: Sized + fmt::Debug + fmt::Display + Clone + Eq + PartialEq> TimerReadRes<T>
1195{
1196    pub 
1197    fn unwrap(self) -> T
1198    {
1199        let Self::Ok(t) = self
1200        else { panic!("can not unwrap {:?}", self)};
1201
1202        return t;
1203    }
1204}
1205
1206/// A tarit which implements standart interface for the MIO crate.
1207#[cfg(feature = "enable_mio_compat")]
1208pub trait TimerFdMioCompat: mio::event::Source + PartialEq<mio::Token>
1209{
1210    /// Gets the event identification token. It is a RawFd of the timer.
1211    fn get_token(&self) -> mio::Token;
1212}
1213
1214
1215/// A super trait which is used on timers for executing the reading code 
1216/// of the timer.
1217/// 
1218/// ## Traits
1219/// 
1220/// * [PartialEq<str>] - compares the timer by its name.
1221/// 
1222/// * [PartialEq<RawFd>] - comares the timer by its FD.
1223pub trait FdTimerRead: AsFd + AsRawFd + fmt::Display + AsRef<str> + PartialEq<str> + PartialEq<RawFd>
1224{
1225    /// Attempts to read the timer. The realization is different on different OS. The main purpose 
1226    /// is to check if timer is ready (ended).
1227    /// 
1228    /// # Returns
1229    /// 
1230    /// * If FD is configured as non-blocking then returns 
1231    ///     [TimerReadRes::WouldBlock] otherwise would block.
1232    /// 
1233    /// * If daytime modification happened the 
1234    ///     [TimerReadRes::Cancelled] will be returned, however
1235    ///     it depends if the [TimerSetTimeFlags::TFD_TIMER_CANCEL_ON_SET]
1236    ///     is set with [TimerSetTimeFlags::TFD_TIMER_ABSTIME]. Does not
1237    ///     work on KQueue implementation.
1238    /// 
1239    /// * If read was successfull the amount of the overflows before
1240    ///     read will be returned i.e [TimerReadRes::Ok]. 
1241    ///     Normally is is `1`. If `0` is returned then probably the
1242    ///     time or day was modified.
1243    /// 
1244    /// * The [Result::Err] is returned if other error occured.
1245    fn read(&self) -> TimerPortResult<TimerReadRes<u64>>;
1246}
1247
1248/// A super trait which implements a marker for the `timer poll` subsystem.
1249/// 
1250/// ## Traits
1251/// 
1252/// * [FdTimerRead] - a sub trait which is a super trait which includes user
1253///     sub-traits.
1254pub trait FdTimerMarker: FdTimerRead + Eq + PartialEq
1255{
1256    fn clone_timer(&self) -> TimerFd;
1257
1258    fn get_strong_count(&self) -> usize;
1259}
1260
1261
1262/// A common trait which is implemented by all timer realizationss for different OSes.
1263pub trait FdTimerCom: FdTimerRead
1264{
1265    /// Creates new isntance of the timer.
1266    /// 
1267    /// # Arguments
1268    /// 
1269    /// * `label` - a [Cow] string which defines a title of the timer for identification.
1270    /// 
1271    /// * `timer_type` - a [TimerType] a clock source
1272    /// 
1273    /// * `timer_flags` - a [TimerFlags] configuration of the timer's FD.
1274    /// 
1275    /// # Returns
1276    /// 
1277    /// A [Result] is retuned with instance on success.
1278    fn new(label: Cow<'static, str>, timer_type: TimerType, timer_flags: TimerFlags) -> TimerPortResult<Self>
1279    where Self: Sized;
1280
1281    /// Sets the timer. The timer starts immidiatly and working depending on the `timer_exp` mode.
1282    /// 
1283    /// In case of timer does not support [TimerExpMode::IntervalDelayed] nativly (on OS level), the
1284    /// crate will store the `interval` part and set interval on first `read()` i.e after the `delay`
1285    /// and remove the stored `interval` (or may not) from the inner field.
1286    fn set_time<TIMERTYPE: ModeTimeType>(&self, timer_exp: TimerExpMode<TIMERTYPE>) -> TimerPortResult<()>;
1287
1288    /// Unsets the timer. The timer stops immidiatly.
1289    fn unset_time(&self) -> TimerPortResult<()>;
1290
1291    /// Sets the timer to non-blocking (on case if `flag` is `true`). 
1292    /// If the timer was inited with
1293    /// [TimerFlags::TFD_NONBLOCK], then this will not do anything. 
1294    fn set_nonblocking(&self, flag: bool) -> TimerPortResult<()>;
1295
1296    /// Reads the FD's flags and check if Fd is in non-blocking mode. 
1297    /// May return error.
1298    /// 
1299    /// # Returns
1300    /// 
1301    /// * `true` - FD is non-blocking
1302    /// 
1303    /// * `false` - FD is blocking
1304    fn is_nonblocking(&self) -> TimerPortResult<bool>;
1305}
1306
1307/// A common abstract type for the timer which is a main instance.
1308/// 
1309/// ## Implements
1310/// 
1311/// This instance implements:
1312/// 
1313/// * [fmt::Display], [AsRawFd], [AsFd], [AsRef], [Eq], [PartialEq], [Deref]
1314/// 
1315/// * [FdTimerMarker], [FdTimerRead]
1316/// 
1317/// * [TimerFdMioCompat] and [mio::event::Source] - if the `feature = enable_mio_compat` is enabled.
1318/// 
1319/// ## Multithread
1320/// 
1321/// A MT-safe, read-only. MT-access is implemented on OS level, so no mutexes
1322/// or other sync is implemented.
1323/// 
1324/// ## Poll
1325/// 
1326/// - A built-in [crate::TimerPoll] can be used.
1327/// 
1328/// - An external crate MIO [TimerFdMioCompat] if `feature = enable_mio_compat` is
1329/// enabled.
1330/// 
1331/// - User implemented poll. The FD can be aquired via [AsRawFd] [AsFd].
1332/// 
1333/// ## Async
1334/// 
1335/// A [Future] is implemented.
1336/// 
1337/// ## Examples
1338/// 
1339/// ```ignore
1340/// let timer = 
1341///     TimerFd::new(Cow::Borrowed("test"), TimerType::CLOCK_REALTIME, 
1342///         TimerFlags::empty()).unwrap();
1343/// 
1344/// timer 
1345/// ```
1346#[repr(transparent)]
1347#[derive(Debug)]
1348pub struct TimerFd(Arc<TimerFdInternal>);
1349
1350
1351#[cfg(feature = "enable_mio_compat")]
1352pub mod mio_compat
1353{
1354    use std::{io, os::fd::{AsRawFd, RawFd}};
1355
1356    use mio::{Token, unix::SourceFd};
1357
1358    use crate::timer_portable::timer::TimerFdMioCompat;
1359
1360    use super::TimerFd;
1361
1362    impl mio::event::Source for TimerFd 
1363    {
1364        fn register(
1365            &mut self,
1366            registry: &mio::Registry,
1367            token: mio::Token,
1368            interests: mio::Interest,
1369        ) -> io::Result<()> 
1370        {
1371            return 
1372                SourceFd(&self.as_raw_fd()).register(registry, token, interests);
1373        }
1374
1375        fn reregister(
1376            &mut self,
1377            registry: &mio::Registry,
1378            token: mio::Token,
1379            interests: mio::Interest,
1380        ) -> io::Result<()> 
1381        {
1382            return 
1383                SourceFd(&self.as_raw_fd()).reregister(registry, token, interests);
1384        }
1385
1386        fn deregister(&mut self, registry: &mio::Registry) -> io::Result<()> 
1387        {
1388            return 
1389                SourceFd(&self.as_raw_fd()).deregister(registry)
1390        }
1391    }
1392
1393    
1394    impl PartialEq<Token> for TimerFd
1395    {
1396        fn eq(&self, other: &Token) -> bool 
1397        {
1398            return self.as_raw_fd() == other.0 as RawFd;
1399        }
1400    }
1401
1402    impl TimerFdMioCompat for TimerFd
1403    { 
1404        fn get_token(&self) -> Token
1405        {
1406            return Token(self.as_raw_fd() as usize);
1407        }
1408    }
1409}
1410
1411impl fmt::Display for TimerFd
1412{
1413    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result 
1414    {
1415        write!(f, "{}", self.0)
1416    }
1417}
1418
1419impl AsFd for TimerFd
1420{
1421    fn as_fd(&self) -> BorrowedFd<'_> 
1422    {
1423        return self.0.as_fd();
1424    }
1425}
1426
1427impl AsRawFd for TimerFd
1428{
1429    fn as_raw_fd(&self) -> RawFd 
1430    {
1431        return self.0.as_raw_fd();
1432    }
1433}
1434impl AsRef<str> for TimerFd
1435{
1436    fn as_ref(&self) -> &str 
1437    {
1438        return self.0.as_ref().as_ref();
1439    }
1440}
1441
1442impl Eq for TimerFd {}
1443
1444impl PartialEq for TimerFd
1445{
1446    fn eq(&self, other: &Self) -> bool 
1447    {
1448        return self.0 == other.0
1449    }
1450}
1451
1452impl PartialEq<RawFd> for TimerFd
1453{
1454    fn eq(&self, other: &RawFd) -> bool 
1455    {
1456        return self.0.as_raw_fd() == *other;
1457    }
1458}
1459
1460impl PartialEq<str> for TimerFd
1461{
1462    fn eq(&self, other: &str) -> bool 
1463    {
1464        return self.0.as_ref() == other;
1465    }
1466}
1467
1468impl FdTimerMarker for TimerFd
1469{
1470    fn clone_timer(&self) -> TimerFd 
1471    {
1472        return Self(self.0.clone());
1473    }
1474
1475    fn get_strong_count(&self) -> usize 
1476    {
1477        return Arc::strong_count(&self.0);
1478    }
1479}
1480
1481/// Returns reference to the timer implementation.
1482impl Deref for TimerFd
1483{
1484    type Target = TimerFdInternal;
1485
1486    fn deref(&self) -> &Self::Target 
1487    {
1488        return self.0.as_ref();
1489    }
1490}
1491
1492impl Future for &TimerFd
1493{
1494    type Output = TimerPortResult<TimerReadRes<u64>>;
1495
1496    fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> 
1497    {
1498        let res = self.get_timer().read();
1499
1500        if let Ok(TimerReadRes::WouldBlock) = res
1501        {
1502            cx.waker().wake_by_ref();
1503
1504            return Poll::Pending;
1505        }
1506        else
1507        {
1508            return Poll::Ready(res);
1509        } 
1510    }
1511}
1512
1513impl Future for TimerFd
1514{
1515    type Output = TimerPortResult<TimerReadRes<u64>>;
1516
1517    fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> 
1518    {
1519        let res = self.get_timer().read();
1520
1521        if let Ok(TimerReadRes::WouldBlock) = res
1522        {
1523            cx.waker().wake_by_ref();
1524
1525            return Poll::Pending;
1526        }
1527        else
1528        {
1529            return Poll::Ready(res);
1530        } 
1531    }
1532}
1533
1534impl TimerFd
1535{
1536    pub 
1537    fn new(label: Cow<'static, str>, timer_type: TimerType, timer_flags: TimerFlags) -> TimerPortResult<Self>
1538    {
1539        return Ok(
1540            Self( Arc::new(TimerFdInternal::new(label, timer_type, timer_flags)?) )
1541        );
1542    }
1543
1544    /// Borrows non-muntable reference to the timer. A [Deref] is implemented for this purpose,
1545    /// but the function was left for compat.
1546    pub 
1547    fn get_timer(&self) -> &TimerFdInternal
1548    {
1549        return &self.0;
1550    }
1551}
1552
1553impl FdTimerRead for TimerFd
1554{
1555    fn read(&self) -> TimerPortResult<TimerReadRes<u64>> 
1556    {
1557        return self.0.read();
1558    }
1559}
1560
1561pub use nix::libc::{itimerspec, timespec};
1562
1563/// Converts from [itimerspec] into [TimerExpMode] of the `TIMERTYPE`.
1564impl<TIMERTYPE: ModeTimeType> From<itimerspec> for TimerExpMode<TIMERTYPE>
1565{
1566    fn from(value: itimerspec) -> Self 
1567    {
1568        if value.it_interval.tv_sec == 0 && value.it_interval.tv_nsec == 0 &&
1569            value.it_value.tv_sec == 0 && value.it_value.tv_nsec == 0
1570        {
1571            // unset
1572            return Self::None;
1573        }
1574        else if value.it_interval.tv_sec == 0 && value.it_interval.tv_nsec == 0
1575        {
1576            // one shot
1577            return 
1578                Self::OneShot
1579                { 
1580                    timeout: TIMERTYPE::from(value.it_value) 
1581                };
1582        }
1583        else if value.it_interval.tv_sec == value.it_value.tv_sec &&
1584            value.it_interval.tv_nsec == value.it_value.tv_nsec
1585        {
1586            // interval
1587            return 
1588                Self::Interval
1589                { 
1590                    interv_tm: TIMERTYPE::from(value.it_interval) 
1591                };
1592        }
1593        else
1594        {
1595            // delayed interval
1596            return 
1597                Self::IntervalDelayed 
1598                { 
1599                    delay_tm: TIMERTYPE::from(value.it_value),
1600                    interv_tm: TIMERTYPE::from(value.it_interval) 
1601                };
1602        }
1603    }
1604}
1605
1606
1607impl<TIMERTYPE: ModeTimeType> From<TimerExpMode<TIMERTYPE>> for itimerspec
1608{
1609    fn from(value: TimerExpMode<TIMERTYPE>) -> Self 
1610    {
1611        return (&value).into();
1612    }
1613}
1614
1615/// Converts from the reference to [TimerExpMode] of the `TIMERTYPE` into the 
1616/// [itimerspec].
1617impl<TIMERTYPE: ModeTimeType> From<&TimerExpMode<TIMERTYPE>> for itimerspec
1618{
1619    fn from(value: &TimerExpMode<TIMERTYPE>) -> Self 
1620    {
1621        match value
1622        {
1623            TimerExpMode::None => 
1624                return 
1625                    itimerspec 
1626                    {
1627                        it_interval: timespec 
1628                        {
1629                            tv_sec: 0,
1630                            tv_nsec: 0,
1631                        },
1632                        it_value: timespec
1633                        {
1634                            tv_sec: 0,
1635                            tv_nsec: 0,
1636                        },
1637                    },
1638            TimerExpMode::OneShot{ timeout} =>
1639                return 
1640                    itimerspec 
1641                    {
1642                        it_interval: timespec 
1643                        {
1644                            tv_sec: 0,
1645                            tv_nsec: 0,
1646                        },
1647                        it_value: timespec
1648                        {
1649                            tv_sec: timeout.get_sec(),
1650                            tv_nsec: timeout.get_nsec(),
1651                        },
1652                    },
1653            TimerExpMode::IntervalDelayed{ delay_tm, interv_tm } => 
1654                return 
1655                    itimerspec 
1656                    {
1657                        it_interval: timespec 
1658                        {
1659                            tv_sec: interv_tm.get_sec(),
1660                            tv_nsec: interv_tm.get_nsec(),
1661                        },
1662                        it_value: timespec
1663                        {
1664                            tv_sec: delay_tm.get_sec(),
1665                            tv_nsec: delay_tm.get_nsec(),
1666                        },
1667                    },
1668            TimerExpMode::Interval{ interv_tm } => 
1669                return 
1670                    itimerspec 
1671                    {
1672                        it_interval: timespec 
1673                        {
1674                            tv_sec: interv_tm.get_sec(),
1675                            tv_nsec: interv_tm.get_nsec(),
1676                        },
1677                        it_value: timespec
1678                        {
1679                            tv_sec: interv_tm.get_sec(),
1680                            tv_nsec: interv_tm.get_nsec(),
1681                        },
1682                    }
1683        }
1684    }
1685}
1686
1687
1688#[cfg(test)]
1689mod tests
1690{
1691
1692    use std::time::Duration;
1693
1694    use crate::{common, timer_portable::timer::{AbsoluteTime, RelativeTime, TimerExpMode}};
1695
1696    #[test]
1697    fn test_0() 
1698    {
1699        let ts = common::get_current_timestamp();
1700
1701        let texp1 = TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts));
1702
1703        assert_eq!(
1704            TimerExpMode::OneShot { timeout: AbsoluteTime::from(ts) },
1705            texp1
1706        );
1707        
1708    }
1709
1710    #[test]
1711    fn test_1() 
1712    {
1713        let ts = common::get_current_timestamp();
1714
1715        let texp1 = 
1716            TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts));
1717
1718        let texp2 = 
1719            texp1 + RelativeTime::new_time(1, 0);
1720
1721        assert_eq!(texp1 < texp2, true);
1722        assert_eq!(texp2 > texp1, true);
1723        assert_eq!(texp2 != texp1, true);
1724        assert_eq!(texp2 < texp1, false);
1725    }
1726
1727    #[test]
1728    fn test_2() 
1729    {
1730
1731        let texp1 = 
1732            TimerExpMode::<AbsoluteTime>::new_oneshot(
1733                unsafe {AbsoluteTime::new_time_unchecked(100, AbsoluteTime::MAX_NS)}
1734            );
1735       
1736        let texp2 = 
1737            texp1 + RelativeTime::new_time(0, 1);
1738
1739
1740        assert_eq!(texp1 < texp2, true);
1741        assert_eq!(texp2 > texp1, true);
1742        assert_eq!(texp2 != texp1, true);
1743        assert_eq!(texp2 < texp1, false);
1744    }
1745
1746    #[test]
1747    fn test_timer_from_test() 
1748    {
1749        let abs1 = AbsoluteTime::from((100, 200));
1750        assert_eq!(abs1.time_sec, 100);
1751        assert_eq!(abs1.time_nsec, 200);
1752
1753        let abs2 = AbsoluteTime::from(0x0000_0000_0000_00FF_0000_0000_0000_0AAA as u128);
1754        assert_eq!(abs2.time_sec, 0xFF);
1755        assert_eq!(abs2.time_nsec, 0xAAA);
1756
1757        let abs3 = AbsoluteTime::from(400 as u64);
1758        assert_eq!(abs3.time_sec, 400);
1759        assert_eq!(abs3.time_nsec, 0);
1760
1761        let abs4 = AbsoluteTime::from(Duration::new(456, 123456));
1762        assert_eq!(abs4.time_sec, 456);
1763        assert_eq!(abs4.time_nsec, 123456);
1764    }
1765
1766    #[should_panic]
1767    #[test]
1768    fn test_2_fail() 
1769    {
1770        let ts = common::get_current_timestamp();
1771
1772        let texp1 = 
1773            TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts));
1774
1775        let texp2 = 
1776            TimerExpMode::<AbsoluteTime>::Interval { interv_tm:  AbsoluteTime::from(ts)};
1777
1778        assert_eq!(texp1 == texp2, true);
1779    }
1780
1781    #[test]
1782    fn test_abstime_cmp()
1783    {
1784        let abs_time = AbsoluteTime::now();
1785        let abs_time_future = abs_time + RelativeTime::new_time(10, 1);
1786        let abs_time_past = abs_time - RelativeTime::new_time(10, 1);
1787
1788        assert_eq!(abs_time < abs_time_future, true);
1789        assert_eq!(abs_time_future > abs_time, true);
1790        assert_eq!(abs_time > abs_time_past, true);
1791        assert_eq!(abs_time_past < abs_time, true);
1792        assert_eq!(abs_time_future > abs_time_past, true);
1793        assert_eq!(abs_time_past < abs_time_future, true);
1794    }
1795
1796    #[test]
1797    fn test_abstime_new()
1798    {
1799        let abs = AbsoluteTime::new_time(1, 999_999_999).unwrap();
1800        assert_eq!(abs.time_nsec, 999_999_999);
1801        assert_eq!(abs.time_sec, 1);
1802
1803        let abs = AbsoluteTime::new_time(1, 1_000_000_000).unwrap();
1804        assert_eq!(abs.time_nsec, 0);
1805        assert_eq!(abs.time_sec, 2);
1806
1807        let abs = AbsoluteTime::new_time(1, 1_000_000_001).unwrap();
1808        assert_eq!(abs.time_nsec, 1);
1809        assert_eq!(abs.time_sec, 2);
1810
1811        let abs = AbsoluteTime::new_time(1, 2_000_000_001).unwrap();
1812        assert_eq!(abs.time_nsec, 1);
1813        assert_eq!(abs.time_sec, 3);
1814    }
1815
1816    #[test]
1817    fn test_abstime_add()
1818    {
1819        let mut abs = AbsoluteTime::new_time(1, 999_999_999).unwrap();
1820
1821        abs += RelativeTime::new_time(0, 1);
1822
1823        assert_eq!(abs.time_nsec, 0);
1824        assert_eq!(abs.time_sec, 2);
1825
1826        abs += RelativeTime::new_time(1, 1);
1827
1828        assert_eq!(abs.time_nsec, 1);
1829        assert_eq!(abs.time_sec, 3);
1830
1831        abs += RelativeTime::new_time(0, 999_999_999);
1832
1833        assert_eq!(abs.time_nsec, 0);
1834        assert_eq!(abs.time_sec, 4);
1835
1836        abs -= RelativeTime::new_time(0, 999_999_999);
1837
1838        assert_eq!(abs.time_nsec, 1);
1839        assert_eq!(abs.time_sec, 3);
1840
1841        abs -= RelativeTime::new_time(0, 1);
1842
1843        assert_eq!(abs.time_nsec, 0);
1844        assert_eq!(abs.time_sec, 3);
1845
1846        abs -= RelativeTime::new_time(0, 500_000_000);
1847
1848        assert_eq!(abs.time_nsec, 500_000_000);
1849        assert_eq!(abs.time_sec, 2);
1850
1851        abs -= RelativeTime::new_time(0, 400_000_000);
1852
1853        assert_eq!(abs.time_nsec, 100_000_000);
1854        assert_eq!(abs.time_sec, 2);
1855
1856        abs -= RelativeTime::new_time(1, 200_000_000);
1857
1858        assert_eq!(abs.time_nsec, 900_000_000);
1859        assert_eq!(abs.time_sec, 0);
1860    }
1861}
1862
1863#[cfg(feature = "enable_mio_compat")]
1864#[cfg(test)]
1865mod tests_mio_compat
1866{
1867    use std::time::Duration;
1868
1869    use mio::{Events, Interest, Poll};
1870
1871    use crate::{AbsoluteTime, FdTimerCom, RelativeTime, TimerReadRes, timer_portable::{TimerExpMode, TimerFd, TimerFdMioCompat, TimerFlags, TimerType, timer::{FdTimerRead, ModeTimeType}}};
1872
1873    fn test1_handle(id: u64, time_dif: i64, timer_tm: AbsoluteTime, events: &Events, timer: &TimerFd)
1874    {
1875        let timer_tm_end = AbsoluteTime::now();
1876        let timer_tm_dif = timer_tm_end - timer_tm;
1877
1878        println!("timer{}: armed: {} event: {} dif: {}", id, timer_tm, timer_tm_end, timer_tm_dif);
1879
1880        assert_eq!(timer_tm_dif.get_sec(), time_dif);
1881
1882        let mut ev_iter = events.iter();
1883
1884        let event1 = ev_iter.next();
1885        assert_eq!(event1.is_some(), true);
1886
1887        let event1 = event1.unwrap();
1888
1889        assert_eq!(event1.token(), timer.get_token());
1890
1891        let timer1_res = timer.read().unwrap();
1892
1893        assert_eq!(timer1_res, TimerReadRes::Ok(1));
1894
1895        // no events should left
1896        assert_eq!(ev_iter.next().is_none(), true);
1897    }
1898
1899    #[test]
1900    fn mio_test1()
1901    {
1902        let mut poll = Poll::new().unwrap();
1903        let mut events = Events::with_capacity(2);
1904
1905        let mut timer1 = 
1906            TimerFd::new("timer1".into(), TimerType::CLOCK_REALTIME, 
1907                TimerFlags::TFD_NONBLOCK)
1908                .unwrap();
1909
1910        let mut timer2 = 
1911            TimerFd::new("timer2".into(), TimerType::CLOCK_REALTIME, 
1912                TimerFlags::TFD_NONBLOCK)
1913                .unwrap();
1914
1915        let tok = timer1.get_token();
1916
1917        poll
1918            .registry()
1919            .register(&mut timer1, tok, Interest::READABLE)
1920            .unwrap();
1921
1922        let tok = timer2.get_token();
1923
1924        poll
1925            .registry()
1926            .register(&mut timer2, tok, Interest::READABLE)
1927            .unwrap();
1928
1929        let timer_tm = AbsoluteTime::now();
1930
1931        // set to relative 2 sec
1932        timer1.set_time(TimerExpMode::<RelativeTime>::new_oneshot(2 as i64)).unwrap();
1933
1934        // set to relative 3 sec
1935        timer2.set_time(TimerExpMode::<RelativeTime>::new_oneshot(3 as i64)).unwrap();
1936
1937        // wait for timer 1
1938        poll.poll(&mut events, Some(Duration::from_millis(2500))).unwrap();
1939    
1940        test1_handle(1, 2, timer_tm, &events, &timer1);
1941        // --- timer 1 end
1942
1943        // poll again
1944        // wait for timer 2
1945        poll.poll(&mut events, Some(Duration::from_millis(1300))).unwrap();
1946
1947        test1_handle(2, 3, timer_tm, &events, &timer2);
1948
1949    }
1950}
1951
1952#[cfg(test)]
1953mod test_timer_fd
1954{
1955    use std::time::{Duration, Instant};
1956
1957    use tokio::io::{unix::AsyncFd, Interest};
1958
1959    use crate::timer_portable::timer::AbsoluteTime;
1960
1961    use super::*;
1962
1963    #[test]
1964    fn test1()
1965    {
1966        let timer = 
1967            TimerFd::new(Cow::Borrowed("test"), TimerType::CLOCK_REALTIME, 
1968                TimerFlags::empty()).unwrap();
1969
1970        let now = chrono::offset::Local::now().timestamp();
1971        let snow = now + 3;
1972        let s = Instant::now();
1973
1974        let timer_mode1 = 
1975            TimerExpMode::<AbsoluteTime>::new_oneshot(
1976                AbsoluteTime::new_time(snow, 0).unwrap()
1977            );
1978
1979        let timer_mode1 = 
1980            TimerExpMode::<AbsoluteTime>::new_oneshot(
1981                Duration::from_secs(snow as u64)
1982            );
1983
1984        let res = 
1985            timer
1986                .set_time(timer_mode1);
1987        println!("timer was set: '{}' '{}'", now, snow);
1988
1989        assert_eq!(res.is_ok(), true, "{}", res.err().unwrap());
1990
1991        
1992
1993        let ovf = timer.read().unwrap().unwrap();
1994
1995        let ts = chrono::offset::Local::now().timestamp();
1996        let e = s.elapsed();
1997
1998        assert_eq!(ovf, 1);
1999        assert_eq!(ts, snow);
2000
2001        println!("elapsed: {:?}, ts: {}", e, ts);
2002
2003        assert_eq!((e.as_millis() <= 3100), true);
2004
2005        println!("Success");
2006        return;
2007    }
2008
2009    #[test]
2010    fn test1_1()
2011    {
2012        let timer = 
2013            TimerFdInternal::new(Cow::Borrowed("test"), TimerType::CLOCK_REALTIME, 
2014                TimerFlags::empty()).unwrap();
2015
2016
2017 let ts = common::get_current_timestamp();
2018        
2019
2020        let timer1_time = 
2021            TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts) + RelativeTime::new_time(3, 0));
2022
2023        timer.set_time(timer1_time).unwrap();
2024        //timer1.set_time(time2_time).unwrap();
2025
2026        
2027        
2028        let res = timer.read().unwrap();
2029
2030         let ts = common::get_current_timestamp();
2031        
2032
2033        let timer1_time = 
2034            TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts) + RelativeTime::new_time(3, 0));
2035
2036        timer.set_time(timer1_time).unwrap();
2037        //timer1.set_time(time2_time).unwrap();
2038
2039        
2040        
2041        let res = timer.read().unwrap();
2042
2043        println!("Success");
2044        return;
2045    }
2046
2047    #[tokio::test]
2048    async fn test2_fut()
2049    {
2050        let timer = 
2051            TimerFd::new(Cow::Borrowed("test"), TimerType::CLOCK_REALTIME, 
2052                TimerFlags::empty()).unwrap();
2053
2054        let now = chrono::offset::Local::now().timestamp();
2055        let snow = now + 3;
2056        let s = Instant::now();
2057
2058        let timer_mode1 = 
2059            TimerExpMode::<AbsoluteTime>::new_oneshot(
2060                AbsoluteTime::new_time(snow, 0).unwrap()
2061            );
2062
2063
2064        let res = 
2065            timer
2066                .set_time(timer_mode1);
2067
2068        println!("timer was set: '{}' '{}'", now, snow);
2069
2070        assert_eq!(res.is_ok(), true, "{}", res.err().unwrap());
2071
2072        //let res = timer.await;
2073
2074        //println!("{:?}", res);
2075        tokio::select! {
2076            ovf = timer => {
2077                let ts = chrono::offset::Local::now().timestamp();
2078                let e = s.elapsed();
2079
2080                assert_eq!(ovf, Ok(TimerReadRes::Ok(1)));
2081                assert_eq!(ts, snow);
2082
2083                println!("timeout e: {:?}, ts:{} snow:{}", e, ts, snow);
2084            }
2085        }
2086    }
2087
2088    #[tokio::test]
2089    async fn test3_tokio()
2090    {
2091        let mut timer: AsyncFd<TimerFd> = 
2092            AsyncFd::with_interest(
2093                TimerFd::new(Cow::Borrowed("test"), TimerType::CLOCK_REALTIME, 
2094                        TimerFlags::empty()).unwrap(), 
2095                Interest::READABLE
2096            ).unwrap();
2097            
2098
2099        let now = chrono::offset::Local::now().timestamp();
2100        let snow = now + 3;
2101        let s = Instant::now();
2102
2103        let timer_mode1 = 
2104            TimerExpMode::<AbsoluteTime>::new_oneshot(
2105                AbsoluteTime::new_time(snow, 0).unwrap()
2106            );
2107
2108        let res = 
2109            timer
2110                .get_mut()
2111                .set_time(timer_mode1);
2112
2113        println!("timer was set: '{}' '{}'", now, snow);
2114
2115        assert_eq!(res.is_ok(), true, "{}", res.err().unwrap());
2116
2117        tokio::select! {
2118            read_guard_res = timer.ready(Interest::READABLE) => 
2119            {
2120                let read_guard = read_guard_res.unwrap();
2121
2122                let res = read_guard.get_inner().read();
2123
2124                let ts = chrono::offset::Local::now().timestamp();
2125                let e = s.elapsed();
2126
2127                assert_eq!(res, Ok(TimerReadRes::Ok(1)));
2128                assert_eq!(ts, snow);
2129
2130                println!("timeout e: {:?}, ts:{} snow:{}", e, ts, snow);
2131            }
2132        }
2133    }
2134
2135    #[test]
2136    fn test4_cancel()
2137    {
2138        let timer = 
2139            TimerFd::new(Cow::Borrowed("test"), TimerType::CLOCK_REALTIME,
2140                TimerFlags::TFD_NONBLOCK).unwrap();
2141
2142        let now = chrono::offset::Local::now().timestamp();
2143        let snow = now + 3;
2144        let s = Instant::now();
2145
2146        let timer_mode1 = 
2147            TimerExpMode::<AbsoluteTime>::new_oneshot(
2148                AbsoluteTime::new_time(snow, 0).unwrap()
2149            );
2150
2151        let res = 
2152            timer
2153                .set_time(timer_mode1);
2154        println!("timer was set: '{}' '{}'", now, snow);
2155
2156        assert_eq!(res.is_ok(), true, "{}", res.err().unwrap());
2157
2158       
2159
2160        let ovf = timer.read().unwrap();
2161
2162        println!("{}", ovf);
2163
2164        timer.unset_time().unwrap();
2165
2166        let ovf = timer.read().unwrap();
2167
2168         println!("{}", ovf);
2169        /*let ts = chrono::offset::Local::now().timestamp();
2170        let e = s.elapsed();
2171
2172        assert_eq!(ovf, 1);
2173        assert_eq!(ts, snow);
2174
2175        println!("elapsed: {:?}, ts: {}", e, ts);
2176
2177        assert_eq!((e.as_millis() <= 3100), true);
2178
2179        println!("Success");
2180        return;*/
2181    }
2182    
2183    #[test]
2184    fn test5_preiodic_with_delay()
2185    {
2186        let timer = 
2187            TimerFd::new(Cow::Borrowed("test"), TimerType::CLOCK_REALTIME, 
2188                TimerFlags::empty()).unwrap();
2189
2190        let timer_mode1 = 
2191            TimerExpMode
2192                ::<RelativeTime>
2193                ::new_interval_with_init_delay(
2194                    RelativeTime::new_time(1, 0), 
2195                    RelativeTime::new_time(0, 500_000_000)
2196                );
2197
2198       
2199
2200        timer.set_time(timer_mode1).unwrap();
2201
2202
2203        let start = AbsoluteTime::now();
2204
2205        let res = timer.read().unwrap();
2206        let end = AbsoluteTime::now();
2207        let diff = end - start;
2208
2209        println!("timer was set s: '{}' e:'{}', diff = '{}' res: '{}'", start, end, diff, res);
2210
2211        assert_eq!(diff.get_sec(), 1);
2212        assert_eq!(res, TimerReadRes::Ok(1));
2213        
2214        let res = timer.read().unwrap();
2215        let end2 = AbsoluteTime::now();
2216        let diff = end2 - end;
2217
2218        println!("timer was set s: '{}' e:'{}', diff = '{}' res: '{}'", end, end2, diff, res);
2219        assert_eq!(diff.get_sec(), 0);
2220        assert!(diff.get_nsec() >= 499_930_000 && diff.get_nsec() <= 500_400_000);
2221        assert_eq!(res, TimerReadRes::Ok(1));
2222
2223        let res = timer.read().unwrap();
2224        let end3 = AbsoluteTime::now();
2225        let diff = end3 - end2;
2226
2227        println!("timer was set s: '{}' e:'{}', diff = '{}' res: '{}'", end2, end3, diff, res);
2228        assert_eq!(diff.get_sec(), 0);
2229        assert!(diff.get_nsec() >= 499_930_000 && diff.get_nsec() <= 500_400_000);
2230        assert_eq!(res, TimerReadRes::Ok(1));
2231
2232        timer.unset_time().unwrap();
2233
2234        timer.set_nonblocking(true).unwrap();
2235
2236        std::thread::sleep(Duration::from_millis(1000));
2237        let res = timer.read().unwrap();
2238
2239        assert_eq!(res, TimerReadRes::WouldBlock);
2240    }
2241}