Skip to content

Commit ce93172

Browse files
scootermoneldruin
authored andcommitted
refactor: migrate to nix Epoll abstraction
1 parent c4f621c commit ce93172

1 file changed

Lines changed: 23 additions & 32 deletions

File tree

src/lib.rs

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ use std::io;
5353
use std::io::prelude::*;
5454
#[cfg(any(target_os = "linux", target_os = "android", feature = "async-tokio"))]
5555
use 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};
5858
use std::path::Path;
5959
use std::{fs, fs::File};
6060

@@ -65,9 +65,7 @@ use mio::event::Source;
6565
#[cfg(feature = "mio-evented")]
6666
use 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")]
7270
use std::task::Poll;
7371
#[cfg(feature = "async-tokio")]
@@ -514,7 +512,9 @@ fn extract_pin_fom_path_test() {
514512
#[derive(Debug)]
515513
pub 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)]
603594
pub struct AsyncPinPoller {

0 commit comments

Comments
 (0)