timer_deque_rs/timer_portable/
poll.rs1use std::{cell::OnceCell, fmt, sync::{Arc, Weak}};
21
22#[cfg(target_family = "unix")]
23use nix::{errno::Errno, sys::eventfd::EventFd};
24
25use crate::
26{
27 FdTimerCom,
28 TimerReadRes,
29 error::{TimerErrorType, TimerResult},
30 map_timer_err,
31 timer_portable::
32 {
33 TimerFd, TimerId, portable_error::TimerPortableErr, timer::{FdTimerMarker}
34 }
35};
36
37#[cfg(target_family = "unix")]
38pub use super::unix::TimerEventWatch;
39
40#[cfg(target_family = "unix")]
41pub type DefaultEventWatch = TimerEventWatch;
42
43#[cfg(target_os = "windows")]
45pub use super::windows::timer_poll::TimerEventWatch;
46
47#[cfg(target_os = "windows")]
48pub type DefaultEventWatch = TimerEventWatch;
49
50#[cfg(target_os = "windows")]
51use super::windows::EventFd;
52
53#[cfg(target_family = "windows")]
54use std::os::windows::io::AsHandle;
55#[derive(Debug, PartialEq, Eq)]
62pub enum PollEventType
63{
64 TimerRes(TimerId, TimerReadRes<u64>),
67
68 SubError(TimerId, TimerPortableErr)
71}
72
73impl fmt::Display for PollEventType
74{
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
76 {
77 match self
78 {
79 Self::TimerRes(timer, res) =>
80 write!(f, "timer {}, res: {}", timer, res),
81 Self::SubError(timer, err) =>
82 write!(f, "timer {}, error: {}", timer, err)
83 }
84 }
85}
86
87impl PollEventType
88{
89 pub
91 fn get_err(&self) -> Option<&TimerPortableErr>
92 {
93 let Self::SubError(_, err) = self
94 else { return None };
95
96 return Some(err);
97 }
98}
99
100#[derive(Debug)]
110pub struct PolledTimerFd<T: FdTimerMarker>
111{
112 arc_timer: OnceCell<T>,
116
117 poll_back_ref: Weak<DefaultEventWatch>
123}
124
125impl<T: FdTimerMarker> fmt::Display for PolledTimerFd<T>
126{
127 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
128 {
129 write!(f, "timer: {}, poll: {}",
130 self.arc_timer.get().unwrap(),
131 self.poll_back_ref.upgrade().map_or("poll instance removed".into(), |f| f.to_string())
132 )
133 }
134}
135
136impl<T: FdTimerMarker> Eq for PolledTimerFd<T> {}
137
138impl<T: FdTimerMarker> PartialEq for PolledTimerFd<T>
139{
140 fn eq(&self, other: &Self) -> bool
141 {
142 return self.arc_timer == other.arc_timer;
143 }
144}
145
146impl<T: FdTimerMarker> PartialEq<str> for PolledTimerFd<T>
147{
148 fn eq(&self, other: &str) -> bool
149 {
150 return self.arc_timer.get().map_or(false, |f| f.as_ref() == other);
151 }
152}
153
154impl<T: FdTimerMarker> AsRef<str> for PolledTimerFd<T>
155{
156 fn as_ref(&self) -> &str
157 {
158 return self.arc_timer.get().unwrap().as_ref().as_ref();
159 }
160}
161
162#[cfg(target_family = "unix")]
163impl<T: FdTimerMarker> Ord for PolledTimerFd<T>
164{
165 fn cmp(&self, other: &Self) -> std::cmp::Ordering
166 {
167 return self.arc_timer.get().unwrap().as_raw_fd().cmp(&other.arc_timer.get().unwrap().as_raw_fd());
168 }
169}
170
171#[cfg(target_family = "windows")]
172impl<T: FdTimerMarker> Ord for PolledTimerFd<T>
173{
174 fn cmp(&self, other: &Self) -> std::cmp::Ordering
175 {
176 return self.arc_timer.get().unwrap().as_raw_handle().cmp(&other.arc_timer.get().unwrap().as_raw_handle());
177 }
178}
179
180impl<T: FdTimerMarker> PartialOrd for PolledTimerFd <T>
181{
182 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering>
183 {
184 return Some(self.cmp(other));
185 }
186}
187
188impl<T: FdTimerMarker> Drop for PolledTimerFd<T>
189{
190 fn drop(&mut self)
191 {
192 let Some(t) = self.arc_timer.take()
193 else { return };
194
195 let Some(poll_ref) = self.poll_back_ref.upgrade()
196 else { return };
197
198 let _ = poll_ref.delete(&t);
200 }
201}
202
203impl<T: FdTimerMarker> PolledTimerFd<T>
204{
205 fn attached_timer(timer: T, poll: Weak<DefaultEventWatch>) -> TimerResult<Self>
221 {
222 let once = OnceCell::new();
223 once.get_or_init(|| timer);
224
225 return Ok(
226 Self
227 {
228 arc_timer:
229 once,
230 poll_back_ref:
231 poll
232 }
233 );
234 }
235
236 pub
243 fn detach_timer(mut self) -> Result<T, Self>
244 {
245 if self.arc_timer.get().unwrap().get_strong_count() > 2
249 {
250 return Err(self);
251 }
252
253 if let Some(poll_ref) = self.poll_back_ref.upgrade()
254 {
255 let _ = poll_ref.delete(self.arc_timer.get().unwrap());
256 }
257
258
259 let timer = self.arc_timer.take().unwrap();
260
261 return Ok(timer);
262 }
263
264 pub
268 fn is_poll_valid(&self) -> bool
269 {
270 return self.poll_back_ref.upgrade().is_some();
271 }
272
273 pub
275 fn get_inner(&self) -> &T
276 {
277 return self.arc_timer.get().unwrap();
278 }
279
280 pub
282 fn get_inner_mut(&mut self) -> &mut T
283 {
284 return self.arc_timer.get_mut().unwrap();
285 }
286}
287
288
289pub trait TimerPollOps
291{
292 fn new() -> TimerResult<Self> where Self: Sized;
298
299 fn add(&self, timer: TimerFd) -> TimerResult<()>;
311
312 fn delete<FD: FdTimerMarker>(&self, timer: &FD) -> TimerResult<()>;
322
323 fn poll(&self, timeout: Option<i32>) -> TimerResult<Option<Vec<PollEventType>>>;
350
351 fn get_count(&self) -> usize;
353
354 fn get_poll_interruptor(&self) -> PollInterrupt;
356
357 fn interrupt_poll(&self) -> bool;
359}
360
361#[derive(Debug)]
362pub struct PollInterruptAq(Arc<EventFd>);
363
364impl PollInterruptAq
365{
366 pub
367 fn interrupt(&self) -> TimerResult<()>
368 {
369 return
370 self
371 .0
372 .write(1)
373 .map_err(|e|
374 map_timer_err!(TimerErrorType::EPoll(e), "can not interrupt POLL!")
375 )
376 .map(|_| ());
377 }
378
379 pub
380 fn interrupt_drop(self) -> TimerResult<()>
381 {
382 return
383 self.interrupt();
384 }
385}
386
387#[derive(Debug, Clone)]
389pub struct PollInterrupt(Weak<EventFd>);
390
391impl PollInterrupt
392{
393 pub(crate)
394 fn new(ev_weak: Weak<EventFd>) -> Self
395 {
396 return Self(ev_weak);
397 }
398
399 #[cfg(target_family = "unix")]
400 pub
401 fn aquire(&self) -> TimerResult<PollInterruptAq>
402 {
403 return
404 self
405 .0
406 .upgrade()
407 .ok_or_else(||
408 map_timer_err!(TimerErrorType::EPoll(Errno::EINVAL), "timer poll has gone and not active!")
409 )
410 .map(|v| PollInterruptAq(v));
411 }
412
413 #[cfg(target_family = "windows")]
414 pub
415 fn aquire(&self) -> TimerResult<PollInterruptAq>
416 {
417 use windows::core::Error;
418
419 return
420 self
421 .0
422 .upgrade()
423 .ok_or_else(||
424 map_timer_err!(TimerErrorType::EPoll(Error::empty()), "timer poll has gone and not active!")
425 )
426 .map(|v| PollInterruptAq(v));
427 }
428}
429
430#[repr(transparent)]
447#[derive(Debug, Clone)]
448pub struct TimerPoll(Arc<DefaultEventWatch>);
449
450impl fmt::Display for TimerPoll
451{
452 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
453 {
454 write!(f, "{}", self.0.as_ref())
455 }
456}
457
458impl TimerPoll
459{
460 #[inline]
461 fn get_timer(&self) -> &DefaultEventWatch
462 {
463 return &self.0;
464 }
465
466 pub
468 fn new() -> TimerResult<Self>
469 {
470 return Ok( Self( Arc::new(DefaultEventWatch::new()?) ) );
471 }
472
473 pub(super)
474 fn downgrade(&self) -> Weak<DefaultEventWatch>
475 {
476 return Arc::downgrade(&self.0);
477 }
478
479 pub
495 fn add<T: FdTimerMarker>(&self, timer: T) -> TimerResult<PolledTimerFd<T>>
496 {
497 let timer_fd: TimerFd = timer.clone_timer();
498
499 let timer_fd_status =
501 timer_fd
502 .get_timer()
503 .is_nonblocking()
504 .map_err(|e|
505 map_timer_err!(TimerErrorType::TimerError(e.get_errno()),
506 "timer: '{}', is_nonblocking error: '{}'", timer_fd, e)
507 )?;
508
509 if timer_fd_status == false
510 {
511 timer_fd
513 .get_timer()
514 .set_nonblocking(true)
515 .map_err(|e|
516 map_timer_err!(TimerErrorType::TimerError(e.get_errno()),
517 "timer: '{}', set_nonblocking error: '{}'", timer_fd, e)
518 )?
519 }
520
521 self.get_timer().add(timer.clone_timer())?;
522
523 return PolledTimerFd::attached_timer(timer, self.downgrade());
524 }
525
526 #[inline]
548 pub
549 fn poll(&self, timeout: Option<i32>) -> TimerResult<Option<Vec<PollEventType>>>
550 {
551 return self.get_timer().poll(timeout);
552 }
553
554 #[inline]
557 pub
558 fn get_poll_interruptor(&self) -> PollInterrupt
559 {
560 return self.get_timer().get_poll_interruptor();
561 }
562
563 #[inline]
565 pub
566 fn interrupt_poll(&self) -> bool
567 {
568 return self.get_timer().interrupt_poll();
569 }
570}
571
572
573#[cfg(test)]
574mod tests
575{
576 use std::{borrow::Cow};
577
578 use crate::{FdTimerCom, RelativeTime, TimerPoll, common, timer_portable::{AsTimerId, TimerExpMode, TimerFlags, TimerType, timer::{AbsoluteTime, TimerFd}}};
579
580 use super::*;
581
582 #[test]
583 fn test_poller_1()
584 {
585
586 let timer1 =
587 TimerFd::new("test".into(), TimerType::CLOCK_REALTIME, TimerFlags::TFD_NONBLOCK)
588 .unwrap();
589
590
591 let poll = TimerPoll::new().unwrap();
592
593 let polled_timer1 = poll.add(timer1).unwrap();
594
595 let tss_set = AbsoluteTime::now().add_sec(2);
596 let tss_tm = TimerExpMode::<AbsoluteTime>::new_oneshot(tss_set);
597
598 polled_timer1.get_inner().get_timer().set_time(tss_tm).unwrap();
599
600 let measure_s = AbsoluteTime::now();
601
602 let res =poll.poll(None).unwrap();
603
604 let measure_e = AbsoluteTime::now();
605
606 println!("poll took: {}", measure_e - measure_s);
607
608 assert_eq!(res.is_some(), true);
609 assert_eq!(res.as_ref().unwrap().len(), 1);
610
611 let k = &res.unwrap()[0];
612
613 let PollEventType::TimerRes(timer_id, timerres) = k
614 else { panic!("wrong type {}", k) };
615
616 assert_eq!(polled_timer1.get_inner().as_timer_id(), *timer_id);
617 assert_eq!(*timerres, crate::TimerReadRes::Ok(1));
618 }
619
620 #[test]
621 fn test_poller_2()
622 {
623 let ts = common::get_current_timestamp();
624
625 let timer1 =
626 TimerFd::new(Cow::Borrowed("test1"), TimerType::CLOCK_REALTIME, TimerFlags::TFD_NONBLOCK)
627 .unwrap();
628
629 let timer1_time =
630 TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts) + RelativeTime::new_time(2, 0));
631
632 let timer2 =
633 TimerFd::new(Cow::Borrowed("test2"), TimerType::CLOCK_REALTIME, TimerFlags::TFD_NONBLOCK)
634 .unwrap();
635
636 let timer2_time =
637 TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts) + RelativeTime::new_time(3, 0));
638
639
640
641 let poll = TimerPoll::new().unwrap();
642
643 let timer1 = poll.add(timer1).unwrap();
644 let timer2 = poll.add(timer2).unwrap();
645
646 timer1.get_inner().get_timer().set_time(timer1_time).unwrap();
647 timer2.get_inner().get_timer().set_time(timer2_time).unwrap();
648
649
650 let res = poll.poll(None).unwrap();
651
652 println!("{:?}", res);
653
654 for i in res.unwrap()
655 {
656 println!("{:?}", i);
657 }
658
659 let res = poll.poll(None);
660 assert_eq!(res.is_ok(), true);
661 println!("{:?}", res);
662
663 let res = poll.poll(Some(1000));
664 println!("{:?}", res);
665 assert_eq!(res.is_err(), false);
666 assert_eq!(res.unwrap().is_none(), true);
667
668
669
670 drop(timer2);
671 }
672}
673
674