timer_deque_rs/timer_portable/
poll.rs1use std::{cell::OnceCell, fmt, os::fd::{AsFd, RawFd}, sync::{Arc, Weak}};
19
20use nix::{errno::Errno, sys::eventfd::EventFd};
21
22use crate::
23{
24 FdTimerCom,
25 TimerReadRes, error::{TimerErrorType, TimerResult}, map_timer_err, timer_portable::{TimerFd, portable_error::TimerPortableErr, timer::{FdTimerMarker, FdTimerRead}}
26};
27
28#[cfg(target_os = "linux")]
29pub use super::linux::timer_poll::TimerEventWatch;
30
31#[cfg(target_os = "linux")]
32pub type DefaultEventWatch = TimerEventWatch;
33
34#[cfg(
35 any(
36 target_os = "freebsd",
37 target_os = "dragonfly",
38 target_os = "netbsd",
39 target_os = "openbsd",
40 target_os = "macos",
41 )
42)]
43pub use super::bsd::TimerEventWatch;
44
45#[cfg(any(
46 target_os = "freebsd",
47 target_os = "dragonfly",
48 target_os = "netbsd",
49 target_os = "openbsd",
50 target_os = "macos",
51))]
52pub type DefaultEventWatch = TimerEventWatch;
53
54#[derive(Debug, PartialEq, Eq)]
58pub enum PollEventType
59{
60 TimerRes(RawFd, TimerReadRes<u64>),
63
64 SubError(RawFd, TimerPortableErr)
67}
68
69impl fmt::Display for PollEventType
70{
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
72 {
73 match self
74 {
75 Self::TimerRes(timer, res) =>
76 write!(f, "timer {}, res: {}", timer, res),
77 Self::SubError(timer, err) =>
78 write!(f, "timer {}, error: {}", timer, err)
79 }
80 }
81}
82
83impl PollEventType
84{
85 pub
87 fn get_err(&self) -> Option<&TimerPortableErr>
88 {
89 let Self::SubError(_, err) = self
90 else { return None };
91
92 return Some(err);
93 }
94}
95
96#[derive(Debug)]
106pub struct PolledTimerFd<T: FdTimerMarker>
107{
108 arc_timer: OnceCell<T>,
112
113 poll_back_ref: Weak<DefaultEventWatch>
119}
120
121impl<T: FdTimerMarker> fmt::Display for PolledTimerFd<T>
122{
123 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
124 {
125 write!(f, "timer: {}, poll: {}",
126 self.arc_timer.get().unwrap(),
127 self.poll_back_ref.upgrade().map_or("poll instance removed".into(), |f| f.to_string())
128 )
129 }
130}
131
132impl<T: FdTimerMarker> Eq for PolledTimerFd<T> {}
133
134impl<T: FdTimerMarker> PartialEq for PolledTimerFd<T>
135{
136 fn eq(&self, other: &Self) -> bool
137 {
138 return self.arc_timer == other.arc_timer;
139 }
140}
141
142impl<T: FdTimerMarker> PartialEq<RawFd> for PolledTimerFd<T>
143{
144 fn eq(&self, other: &RawFd) -> bool
145 {
146 return self.arc_timer.get().map_or(false, |f| f == other);
147 }
148}
149
150impl<T: FdTimerMarker> PartialEq<str> for PolledTimerFd<T>
151{
152 fn eq(&self, other: &str) -> bool
153 {
154 return self.arc_timer.get().map_or(false, |f| f.as_ref() == other);
155 }
156}
157
158impl<T: FdTimerMarker> AsRef<str> for PolledTimerFd<T>
159{
160 fn as_ref(&self) -> &str
161 {
162 return self.arc_timer.get().unwrap().as_ref().as_ref();
163 }
164}
165
166
167impl<T: FdTimerMarker> Ord for PolledTimerFd<T>
168{
169 fn cmp(&self, other: &Self) -> std::cmp::Ordering
170 {
171 return self.arc_timer.get().unwrap().as_raw_fd().cmp(&other.arc_timer.get().unwrap().as_raw_fd());
172 }
173}
174
175impl<T: FdTimerMarker> PartialOrd for PolledTimerFd <T>
176{
177 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering>
178 {
179 return Some(self.cmp(other));
180 }
181}
182
183impl<T: FdTimerMarker> Drop for PolledTimerFd<T>
184{
185 fn drop(&mut self)
186 {
187 let Some(t) = self.arc_timer.take()
188 else { return };
189
190 let Some(poll_ref) = self.poll_back_ref.upgrade()
191 else { return };
192
193 let _ = poll_ref.delete(&t);
195 }
196}
197
198impl<T: FdTimerMarker> PolledTimerFd<T>
199{
200 fn attached_timer(timer: T, poll: Weak<DefaultEventWatch>) -> TimerResult<Self>
216 {
217 let once = OnceCell::new();
218 once.get_or_init(|| timer);
219
220 return Ok(
221 Self
222 {
223 arc_timer:
224 once,
225 poll_back_ref:
226 poll
227 }
228 );
229 }
230
231 pub
238 fn detach_timer(mut self) -> Result<T, Self>
239 {
240 if self.arc_timer.get().unwrap().get_strong_count() > 2
244 {
245 return Err(self);
246 }
247
248 if let Some(poll_ref) = self.poll_back_ref.upgrade()
249 {
250 let _ = poll_ref.delete(self.arc_timer.get().unwrap().as_fd());
251 }
252
253 let timer = self.arc_timer.take().unwrap();
254
255 return Ok(timer);
256 }
257
258 pub
262 fn is_poll_valid(&self) -> bool
263 {
264 return self.poll_back_ref.upgrade().is_some();
265 }
266
267 pub
269 fn get_inner(&self) -> &T
270 {
271 return self.arc_timer.get().unwrap();
272 }
273
274 pub
276 fn get_inner_mut(&mut self) -> &mut T
277 {
278 return self.arc_timer.get_mut().unwrap();
279 }
280}
281
282
283pub trait TimerPollOps
285{
286 fn new() -> TimerResult<Self> where Self: Sized;
292
293 fn add(&self, timer: TimerFd) -> TimerResult<()>;
305
306 fn delete<FD: AsFd>(&self, timer: FD) -> TimerResult<()>;
316
317 fn poll(&self, timeout: Option<i32>) -> TimerResult<Option<Vec<PollEventType>>>;
344
345 fn get_count(&self) -> usize;
347
348 fn get_poll_interruptor(&self) -> PollInterrupt;
350
351 fn interrupt_poll(&self) -> bool;
353}
354
355#[derive(Debug)]
356pub struct PollInterruptAq(Arc<EventFd>);
357
358impl PollInterruptAq
359{
360 pub
361 fn interrupt(&self) -> TimerResult<()>
362 {
363 return
364 self
365 .0
366 .write(1)
367 .map_err(|e|
368 map_timer_err!(TimerErrorType::EPoll(e), "can not interrupt POLL!")
369 )
370 .map(|_| ());
371 }
372
373 pub
374 fn interrupt_drop(self) -> TimerResult<()>
375 {
376 return
377 self.interrupt();
378 }
379}
380
381#[derive(Debug, Clone)]
383pub struct PollInterrupt(Weak<EventFd>);
384
385impl PollInterrupt
386{
387 pub
388 fn new(ev_weak: Weak<EventFd>) -> Self
389 {
390 return Self(ev_weak);
391 }
392
393 pub
394 fn aquire(&self) -> TimerResult<PollInterruptAq>
395 {
396 return
397 self
398 .0
399 .upgrade()
400 .ok_or_else(||
401 map_timer_err!(TimerErrorType::EPoll(Errno::EINVAL), "timer poll has gone and not active!")
402 )
403 .map(|v| PollInterruptAq(v));
404 }
405}
406
407#[repr(transparent)]
410#[derive(Debug, Clone)]
411pub struct TimerPoll(Arc<DefaultEventWatch>);
412
413impl fmt::Display for TimerPoll
414{
415 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
416 {
417 write!(f, "{}", self.0.as_ref())
418 }
419}
420
421impl TimerPoll
422{
423 #[inline]
424 fn get_timer(&self) -> &DefaultEventWatch
425 {
426 return &self.0;
427 }
428
429 pub
431 fn new() -> TimerResult<Self>
432 {
433 return Ok( Self( Arc::new(DefaultEventWatch::new()?) ) );
434 }
435
436 pub(super)
437 fn downgrade(&self) -> Weak<DefaultEventWatch>
438 {
439 return Arc::downgrade(&self.0);
440 }
441
442 pub
458 fn add<T: FdTimerMarker>(&self, timer: T) -> TimerResult<PolledTimerFd<T>>
459 {
460 let timer_fd: TimerFd = timer.clone_timer();
461
462 let timer_fd_status =
464 timer_fd
465 .get_timer()
466 .is_nonblocking()
467 .map_err(|e|
468 map_timer_err!(TimerErrorType::TimerError(e.get_errno()),
469 "timer: '{}', is_nonblocking error: '{}'", timer_fd, e)
470 )?;
471
472 if timer_fd_status == false
473 {
474 timer_fd
476 .get_timer()
477 .set_nonblocking(true)
478 .map_err(|e|
479 map_timer_err!(TimerErrorType::TimerError(e.get_errno()),
480 "timer: '{}', set_nonblocking error: '{}'", timer_fd, e)
481 )?
482 }
483
484 self.get_timer().add(timer.clone_timer())?;
485
486 return PolledTimerFd::attached_timer(timer, self.downgrade());
487 }
488
489 #[inline]
511 pub
512 fn poll(&self, timeout: Option<i32>) -> TimerResult<Option<Vec<PollEventType>>>
513 {
514 return self.get_timer().poll(timeout);
515 }
516
517 #[inline]
518 pub
519 fn get_poll_interruptor(&self) -> PollInterrupt
520 {
521 return self.get_timer().get_poll_interruptor();
522 }
523
524 #[inline]
525 pub
526 fn interrupt_poll(&self) -> bool
527 {
528 return self.get_timer().interrupt_poll();
529 }
530}
531
532
533#[cfg(test)]
534mod tests
535{
536 use std::{borrow::Cow, os::fd::AsRawFd};
537
538 use crate::{common, timer_portable::{timer::{AbsoluteTime, TimerFd}, TimerExpMode, TimerFlags, TimerType}, FdTimerCom, RelativeTime, TimerPoll};
539
540 use super::*;
541
542 #[test]
543 fn test_kqueue()
544 {
545
546 let timer1 =
547 TimerFd::new("test".into(), TimerType::CLOCK_REALTIME, TimerFlags::TFD_NONBLOCK)
548 .unwrap();
549
550 let poll = TimerPoll::new().unwrap();
551
552 let polled_timer1 = poll.add(timer1).unwrap();
553
554 let tss_set = AbsoluteTime::now().add_sec(2);
555 let tss_tm = TimerExpMode::<AbsoluteTime>::OneShot { timeout: tss_set };
556
557 polled_timer1.get_inner().get_timer().set_time(tss_tm).unwrap();
558
559 let res =poll.poll(None).unwrap();
560
561 assert_eq!(res.is_some(), true);
562 assert_eq!(res.as_ref().unwrap().len(), 1);
563 assert_eq!(res.unwrap()[0], PollEventType::TimerRes(polled_timer1.get_inner().as_raw_fd(), crate::TimerReadRes::Ok(1)));
564 }
565
566 #[test]
567 fn test_kqueue_1()
568 {
569 let ts = common::get_current_timestamp();
570
571 let timer1 =
572 TimerFd::new(Cow::Borrowed("test1"), TimerType::CLOCK_REALTIME, TimerFlags::TFD_NONBLOCK)
573 .unwrap();
574
575 let timer1_time =
576 TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts) + RelativeTime::new_time(2, 0));
577
578 let timer2 =
579 TimerFd::new(Cow::Borrowed("test2"), TimerType::CLOCK_REALTIME, TimerFlags::TFD_NONBLOCK)
580 .unwrap();
581
582 let timer2_time =
583 TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts) + RelativeTime::new_time(3, 0));
584
585
586
587 let poll = TimerPoll::new().unwrap();
588
589 let timer1 = poll.add(timer1).unwrap();
590 let timer2 = poll.add(timer2).unwrap();
591
592 timer1.get_inner().get_timer().set_time(timer1_time).unwrap();
593 timer2.get_inner().get_timer().set_time(timer2_time).unwrap();
594
595
596 let res = poll.poll(None).unwrap();
597
598 println!("{:?}", res);
599
600 for i in res.unwrap()
601 {
602 println!("{:?}", i);
603 }
604
605 let res = poll.poll(None);
606
607 println!("{:?}", res);
608
609 let res = poll.poll(Some(1000));
610
611 println!("{:?}", res);
612
613 drop(timer2);
614 }
615}
616
617