@@ -20,7 +20,113 @@ pub struct Timer {
2020
2121impl Timer {
2222 pub fn initialize ( self ) -> Self {
23- self
23+ let txs = Arc :: clone ( & self . txs ) ;
24+
25+ // TODO: use ? instead of unwrap, requires changing Timer initialize function
26+ let timer_fd = Timer :: set_timerfd ( ) . unwrap ( ) ;
27+ let epoll_fd = Timer :: create_epollfd ( timer_fd) . unwrap ( ) ;
28+
29+ let handle = Some ( thread:: spawn ( move || {
30+ loop {
31+ // Exit thread if there are no listeners
32+ if txs. lock ( ) ?. len ( ) == 0 {
33+ // TODO: should close file descriptor
34+ return Ok ( ( ) ) ;
35+ }
36+
37+ // Fire @ 10th sec
38+ Timer :: epoll_wait ( timer_fd, epoll_fd) . unwrap ( ) ;
39+
40+ // Get current time
41+ let current = std:: time:: SystemTime :: now ( )
42+ . duration_since ( std:: time:: UNIX_EPOCH ) ?
43+ . as_secs ( ) ;
44+
45+ // Iterate through Senders
46+ txs. lock ( ) ?. iter ( ) . for_each ( |tx| {
47+ // Send event to attached Sender
48+ tx. send ( current) . unwrap ( ) ;
49+ } ) ;
50+ }
51+ } ) ) ;
52+
53+ Self { handle, ..self }
54+ }
55+
56+ fn set_timerfd ( ) -> Result < libc:: c_int > {
57+ let clockid: libc:: clockid_t = libc:: CLOCK_REALTIME ;
58+ let clock_flags: libc:: c_int = libc:: TFD_NONBLOCK ;
59+
60+ // TODO: handler error (-1)
61+ let tfd = unsafe { libc:: timerfd_create ( clockid, clock_flags) } ;
62+
63+ let now = std:: time:: SystemTime :: now ( )
64+ . duration_since ( std:: time:: UNIX_EPOCH ) ?
65+ . as_secs ( ) ;
66+
67+ let rem = 10u64 . checked_sub ( now. checked_rem ( 10 ) . unwrap ( ) ) . unwrap ( ) ;
68+
69+ let first_fire = now + rem;
70+
71+ let mut new_value = libc:: itimerspec {
72+ it_interval : libc:: timespec {
73+ tv_sec : 10 ,
74+ tv_nsec : 0 ,
75+ } ,
76+ it_value : libc:: timespec {
77+ tv_sec : first_fire as i64 ,
78+ tv_nsec : 0 ,
79+ } ,
80+ } ;
81+
82+ let mut old_value = libc:: itimerspec {
83+ it_interval : libc:: timespec {
84+ tv_sec : 0 ,
85+ tv_nsec : 0 ,
86+ } ,
87+ it_value : libc:: timespec {
88+ tv_sec : 0 ,
89+ tv_nsec : 0 ,
90+ } ,
91+ } ;
92+
93+ let set_flags = libc:: TFD_TIMER_ABSTIME ;
94+
95+ // TODO: handler error (-1)
96+ let sfd = unsafe { libc:: timerfd_settime ( tfd, set_flags, & mut new_value, & mut old_value) } ;
97+
98+ Ok ( tfd)
99+ }
100+
101+ fn create_epollfd ( timer_fd : libc:: c_int ) -> Result < libc:: c_int > {
102+ // TODO: handler error (-1)
103+ let epoll_fd = unsafe { libc:: epoll_create1 ( 0 ) } ;
104+
105+ let mut event = libc:: epoll_event {
106+ events : libc:: EPOLLIN as u32 ,
107+ u64 : 1 ,
108+ } ;
109+
110+ let epoll_flags = libc:: EPOLL_CTL_ADD ;
111+
112+ // TODO: handler error (-1)
113+ let ctl_fd = unsafe { libc:: epoll_ctl ( epoll_fd, epoll_flags, timer_fd, & mut event) } ;
114+
115+ Ok ( epoll_fd)
116+ }
117+
118+ fn epoll_wait ( timer_fd : libc:: c_int , epoll_fd : libc:: c_int ) -> Result < ( ) > {
119+ let mut events = Vec :: with_capacity ( 1 ) ;
120+
121+ // TODO: handler error (-1)
122+ let wait = unsafe { libc:: epoll_wait ( epoll_fd, events. as_mut_ptr ( ) , 1 , -1 ) } ;
123+ let mut buffer: u64 = 0 ;
124+ let bufptr: * mut _ = & mut buffer;
125+
126+ // TODO: handler error (-1)
127+ let read = unsafe { libc:: read ( timer_fd, bufptr as * mut libc:: c_void , 8 ) } ;
128+
129+ Ok ( ( ) )
24130 }
25131
26132 /// Attach an mpsc::Sender to Timer
0 commit comments