@@ -20,23 +20,22 @@ pub struct Timer {
2020}
2121
2222impl Timer {
23- pub fn initialize ( self ) -> Self {
23+ pub fn initialize ( self ) -> Result < Self > {
2424 let txs = Arc :: clone ( & self . txs ) ;
2525
26- // TODO: use ? instead of unwrap, requires changing Timer initialize function
27- let timer_fd = Timer :: set_timerfd ( ) . unwrap ( ) ;
28- let epoll_fd = Timer :: create_epollfd ( timer_fd) . unwrap ( ) ;
26+ let timer_fd = Timer :: set_timerfd ( ) ?;
27+ let epoll_fd = Timer :: create_epollfd ( timer_fd) ?;
2928
3029 let handle = Some ( thread:: spawn ( move || {
3130 loop {
3231 // Exit thread if there are no listeners
3332 if txs. lock ( ) ?. len ( ) == 0 {
34- // TODO: should close file descriptor
33+ // TODO: should close file descriptors?
3534 return Ok ( ( ) ) ;
3635 }
3736
3837 // Fire @ 10th sec
39- Timer :: epoll_wait ( timer_fd, epoll_fd) . unwrap ( ) ;
38+ Timer :: epoll_wait ( timer_fd, epoll_fd) ? ;
4039
4140 // Get current time
4241 let current = std:: time:: SystemTime :: now ( )
@@ -51,23 +50,27 @@ impl Timer {
5150 }
5251 } ) ) ;
5352
54- Self { handle, ..self }
53+ Ok ( Self { handle, ..self } )
5554 }
5655
56+ /// create and set a timer file descriptor
5757 fn set_timerfd ( ) -> Result < libc:: c_int > {
58+ // Set the timer to use the system time.
5859 let clockid: libc:: clockid_t = libc:: CLOCK_REALTIME ;
60+ // Non-blocking file descriptor
5961 let clock_flags: libc:: c_int = libc:: TFD_NONBLOCK ;
6062
61- let tfd = timerfd_create ( clockid, clock_flags) . unwrap ( ) ;
63+ // Create timer fd
64+ let tfd = timerfd_create ( clockid, clock_flags) ?;
6265
66+ // Get the next event time
6367 let now = std:: time:: SystemTime :: now ( )
6468 . duration_since ( std:: time:: UNIX_EPOCH ) ?
6569 . as_secs ( ) ;
66-
6770 let rem = 10u64 . checked_sub ( now. checked_rem ( 10 ) . unwrap ( ) ) . unwrap ( ) ;
68-
6971 let first_fire = now + rem;
7072
73+ // new_value sets the Timer
7174 let mut new_value = libc:: itimerspec {
7275 it_interval : libc:: timespec {
7376 tv_sec : 10 ,
@@ -79,6 +82,7 @@ impl Timer {
7982 } ,
8083 } ;
8184
85+ // Empty itimerspec object
8286 let mut old_value = libc:: itimerspec {
8387 it_interval : libc:: timespec {
8488 tv_sec : 0 ,
@@ -92,35 +96,44 @@ impl Timer {
9296
9397 let set_flags = libc:: TFD_TIMER_ABSTIME ;
9498
95- timerfd_settime ( tfd, set_flags, & mut new_value, & mut old_value) . unwrap ( ) ;
99+ // Set the timer
100+ timerfd_settime ( tfd, set_flags, & mut new_value, & mut old_value) ?;
96101
102+ // Return file descriptor
97103 Ok ( tfd)
98104 }
99105
106+ /// Create a new epoll file descriptor and add the timer to its interests
100107 fn create_epollfd ( timer_fd : libc:: c_int ) -> Result < libc:: c_int > {
101- let epoll_fd = epoll_create1 ( 0 ) . unwrap ( ) ;
108+ // create a new epoll fd
109+ let epoll_fd = epoll_create1 ( 0 ) ?;
102110
111+ // event to pull
103112 let mut event = libc:: epoll_event {
104113 events : libc:: EPOLLIN as u32 ,
105114 u64 : 1 ,
106115 } ;
107116
108117 let epoll_flags = libc:: EPOLL_CTL_ADD ;
109118
110- epoll_ctl ( epoll_fd, epoll_flags, timer_fd, & mut event) . unwrap ( ) ;
119+ // add event to the epoll
120+ epoll_ctl ( epoll_fd, epoll_flags, timer_fd, & mut event) ?;
111121
122+ // return epoll fd
112123 Ok ( epoll_fd)
113124 }
114125
115126 fn epoll_wait ( timer_fd : libc:: c_int , epoll_fd : libc:: c_int ) -> Result < ( ) > {
127+ // vector to store events
116128 let mut events = Vec :: with_capacity ( 1 ) ;
117129
118- epoll_wait ( epoll_fd, events. as_mut_ptr ( ) , 1 , -1 ) . unwrap ( ) ;
130+ // wait for the timer to fire an event. This is function will block.
131+ epoll_wait ( epoll_fd, events. as_mut_ptr ( ) , 1 , -1 ) ?;
119132
133+ // read the value from the timerfd. This is required to re-arm the timer.
120134 let mut buffer: u64 = 0 ;
121135 let bufptr: * mut _ = & mut buffer;
122-
123- read ( timer_fd, bufptr as * mut libc:: c_void , 8 ) . unwrap ( ) ;
136+ read ( timer_fd, bufptr as * mut libc:: c_void , 8 ) ?;
124137
125138 Ok ( ( ) )
126139 }
0 commit comments