From a19da404c1395072e51a155de264639b1d0424db Mon Sep 17 00:00:00 2001 From: Jonathan Date: Wed, 23 Nov 2022 20:28:24 +0000 Subject: [PATCH] Epoll type --- src/sys/epoll.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/src/sys/epoll.rs b/src/sys/epoll.rs index 58def2e788..e9f7779710 100644 --- a/src/sys/epoll.rs +++ b/src/sys/epoll.rs @@ -2,7 +2,7 @@ use crate::errno::Errno; use crate::Result; use libc::{self, c_int}; use std::mem; -use std::os::unix::io::RawFd; +use std::os::unix::io::{FromRawFd,RawFd, OwnedFd, AsFd, AsRawFd}; use std::ptr; libc_bitflags!( @@ -26,6 +26,64 @@ libc_bitflags!( } ); +/// A safe wrapper around [`epoll`](https://man7.org/linux/man-pages/man7/epoll.7.html). +/// ``` +/// # use nix::sys::{epoll::{Epoll, EpollEvent, EpollFlags, EpollCreateFlags}, eventfd::{eventfd, EfdFlags}}; +/// # use nix::unistd::write; +/// # use std::os::unix::io::{OwnedFd, FromRawFd, AsRawFd, AsFd}; +/// # use std::time::{Instant, Duration}; +/// # fn main() -> nix::Result<()> { +/// const DATA: u64 = 17; +/// const MILLIS: u64 = 100; +/// +/// // Create epoll +/// let epoll = Epoll::new(EpollCreateFlags::empty())?; +/// +/// // Create eventfd & Add event +/// let eventfd = unsafe { OwnedFd::from_raw_fd(eventfd(0, EfdFlags::empty())?) }; +/// epoll.add(eventfd.as_fd(), EpollEvent::new(EpollFlags::EPOLLIN,DATA))?; +/// +/// // Arm eventfd & Time wait +/// write(eventfd.as_raw_fd(), &1u64.to_ne_bytes())?; +/// let now = Instant::now(); +/// +/// // Wait on event +/// let mut events = [EpollEvent::empty()]; +/// epoll.wait(&mut events, MILLIS as isize); +/// +/// // Assert data correct & timeout didn't occur +/// assert_eq!(events[0].data(), DATA); +/// assert!(now.elapsed() < Duration::from_millis(MILLIS)); +/// # Ok(()) +/// # } +/// ``` +#[derive(Debug)] +pub struct Epoll(pub OwnedFd); +impl Epoll { + /// [`epoll_create1`]. + pub fn new(flags: EpollCreateFlags) -> Result { + let fd = epoll_create1(flags)?; + let owned_fd = unsafe { OwnedFd::from_raw_fd(fd) }; + Ok(Self(owned_fd)) + } + /// [`epoll_ctl`] with [`EpollOp::EpollCtlAdd`]. + pub fn add(&self,fd: impl AsFd, mut event: EpollEvent) -> Result<()> { + epoll_ctl(self.0.as_raw_fd(),EpollOp::EpollCtlAdd,fd.as_fd().as_raw_fd(),&mut event) + } + /// [`epoll_ctl`] with [`EpollOp::EpollCtlDel`]. + pub fn delete(&self, fd: impl AsFd) -> Result<()> { + epoll_ctl(self.0.as_raw_fd(),EpollOp::EpollCtlDel,fd.as_fd().as_raw_fd(),None) + } + /// [`epoll_ctl`] with [`EpollOp::EpollCtlMod`]. + pub fn modify(&self,fd: impl AsFd, event: &mut EpollEvent) -> Result<()> { + epoll_ctl(self.0.as_raw_fd(),EpollOp::EpollCtlMod,fd.as_fd().as_raw_fd(),event) + } + /// [`epoll_wait`] + pub fn wait(&self, events: &mut [EpollEvent], timeout: isize) -> Result { + epoll_wait(self.0.as_raw_fd(),events,timeout) + } +} + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] #[repr(i32)] #[non_exhaustive]