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