@@ -53,8 +53,8 @@ use std::io;
5353use std:: io:: prelude:: * ;
5454#[ cfg( any( target_os = "linux" , target_os = "android" , feature = "async-tokio" ) ) ]
5555use std:: io:: SeekFrom ;
56- #[ cfg( not ( target_os = "wasi " ) ) ]
57- use std:: os:: unix :: prelude :: * ;
56+ #[ cfg( any ( feature = "async-tokio" , feature = "mio-evented ") ) ]
57+ use std:: os:: fd :: { AsRawFd , RawFd } ;
5858use std:: path:: Path ;
5959use std:: { fs, fs:: File } ;
6060
@@ -65,9 +65,7 @@ use mio::event::Source;
6565#[ cfg( feature = "mio-evented" ) ]
6666use mio:: unix:: SourceFd ;
6767#[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
68- use nix:: sys:: epoll:: * ;
69- #[ cfg( not( target_os = "wasi" ) ) ]
70- use nix:: unistd:: close;
68+ use nix:: sys:: epoll:: { Epoll , EpollCreateFlags , EpollEvent , EpollFlags , EpollTimeout } ;
7169#[ cfg( feature = "async-tokio" ) ]
7270use std:: task:: Poll ;
7371#[ cfg( feature = "async-tokio" ) ]
@@ -514,7 +512,9 @@ fn extract_pin_fom_path_test() {
514512#[ derive( Debug ) ]
515513pub struct PinPoller {
516514 pin_num : u64 ,
517- epoll_fd : RawFd ,
515+ #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
516+ epoll : Epoll ,
517+ #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
518518 devfile : File ,
519519}
520520#[ cfg( not( target_os = "wasi" ) ) ]
@@ -531,21 +531,16 @@ impl PinPoller {
531531 #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
532532 pub fn new ( pin_num : u64 ) -> Result < PinPoller > {
533533 let devfile: File = File :: open ( format ! ( "/sys/class/gpio/gpio{}/value" , pin_num) ) ?;
534- let devfile_fd = devfile. as_raw_fd ( ) ;
535- let epoll_fd = epoll_create ( ) ?;
536- let mut event = EpollEvent :: new ( EpollFlags :: EPOLLPRI | EpollFlags :: EPOLLET , 0u64 ) ;
537-
538- match epoll_ctl ( epoll_fd, EpollOp :: EpollCtlAdd , devfile_fd, & mut event) {
539- Ok ( _) => Ok ( PinPoller {
540- pin_num,
541- devfile,
542- epoll_fd,
543- } ) ,
544- Err ( err) => {
545- let _ = close ( epoll_fd) ; // cleanup
546- Err ( :: std:: convert:: From :: from ( err) )
547- }
548- }
534+ let epoll = Epoll :: new ( EpollCreateFlags :: empty ( ) ) ?;
535+ epoll. add (
536+ & devfile,
537+ EpollEvent :: new ( EpollFlags :: EPOLLPRI | EpollFlags :: EPOLLET , 0u64 ) ,
538+ ) ?;
539+ Ok ( PinPoller {
540+ pin_num,
541+ devfile,
542+ epoll,
543+ } )
549544 }
550545
551546 #[ cfg( not( any( target_os = "linux" , target_os = "android" ) ) ) ]
@@ -575,7 +570,13 @@ impl PinPoller {
575570 flush_input_from_file ( & mut self . devfile , 255 ) ?;
576571 let dummy_event = EpollEvent :: new ( EpollFlags :: EPOLLPRI | EpollFlags :: EPOLLET , 0u64 ) ;
577572 let mut events: [ EpollEvent ; 1 ] = [ dummy_event] ;
578- let cnt = epoll_wait ( self . epoll_fd , & mut events, timeout_ms) ?;
573+ // LOGIC: Previous versions essentially passed `timeout_ms as c_int` to the
574+ // kernel without validation. We now validate that the value is in range
575+ // -1..=i32::MAX. A future major version of this library should update
576+ // the `poll` signature.
577+ let timeout = EpollTimeout :: try_from ( timeout_ms as i128 )
578+ . map_err ( |err| Error :: Io ( io:: Error :: other ( err) ) ) ?;
579+ let cnt = self . epoll . wait ( & mut events, timeout) ?;
579580 Ok ( match cnt {
580581 0 => None , // timeout
581582 _ => Some ( get_value_from_file ( & mut self . devfile ) ?) ,
@@ -588,16 +589,6 @@ impl PinPoller {
588589 }
589590}
590591
591- #[ cfg( not( target_os = "wasi" ) ) ]
592- impl Drop for PinPoller {
593- fn drop ( & mut self ) {
594- // we implement drop to close the underlying epoll fd as
595- // it does not implement drop itself. This is similar to
596- // how mio works
597- close ( self . epoll_fd ) . unwrap ( ) ; // panic! if close files
598- }
599- }
600-
601592#[ cfg( feature = "mio-evented" ) ]
602593#[ derive( Debug ) ]
603594pub struct AsyncPinPoller {
0 commit comments