Skip to content

Commit 4613b6e

Browse files
Epoll type
1 parent 33b5f92 commit 4613b6e

File tree

1 file changed

+59
-1
lines changed

1 file changed

+59
-1
lines changed

src/sys/epoll.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::errno::Errno;
22
use crate::Result;
33
use libc::{self, c_int};
44
use std::mem;
5-
use std::os::unix::io::RawFd;
5+
use std::os::unix::io::{FromRawFd,RawFd, OwnedFd, AsFd, AsRawFd};
66
use std::ptr;
77

88
libc_bitflags!(
@@ -26,6 +26,64 @@ libc_bitflags!(
2626
}
2727
);
2828

29+
/// A safe wrapper around [`epoll`](https://man7.org/linux/man-pages/man7/epoll.7.html).
30+
/// ```
31+
/// # use nix::sys::{epoll::{Epoll, EpollEvent, EpollFlags, EpollCreateFlags}, eventfd::{eventfd, EfdFlags}};
32+
/// # use nix::unistd::write;
33+
/// # use std::os::unix::io::{OwnedFd, FromRawFd, AsRawFd, AsFd};
34+
/// # use std::time::{Instant, Duration};
35+
/// # fn main() -> nix::Result<()> {
36+
/// const DATA: u64 = 17;
37+
/// const MILLIS: u64 = 100;
38+
///
39+
/// // Create epoll
40+
/// let epoll = Epoll::new(EpollCreateFlags::empty())?;
41+
///
42+
/// // Create eventfd & Add event
43+
/// let eventfd = unsafe { OwnedFd::from_raw_fd(eventfd(0, EfdFlags::empty())?) };
44+
/// epoll.add(eventfd.as_fd(), EpollEvent::new(EpollFlags::EPOLLIN,DATA))?;
45+
///
46+
/// // Arm eventfd & Time wait
47+
/// write(eventfd.as_raw_fd(), &1u64.to_ne_bytes())?;
48+
/// let now = Instant::now();
49+
///
50+
/// // Wait on event
51+
/// let mut events = [EpollEvent::empty()];
52+
/// epoll.wait(&mut events, MILLIS);
53+
///
54+
/// // Assert data correct & timeout didn't occur
55+
/// assert_eq!(events[0].data(), DATA);
56+
/// assert!(now.elapsed() < Duration::from_millis(MILLIS));
57+
/// # Ok(())
58+
/// # }
59+
/// ```
60+
#[derive(Debug)]
61+
pub struct Epoll(pub OwnedFd);
62+
impl Epoll {
63+
/// [`epoll_create1`].
64+
pub fn new(flags: EpollCreateFlags) -> Result<Self> {
65+
let fd = epoll_create1(flags)?;
66+
let owned_fd = unsafe { OwnedFd::from_raw_fd(fd) };
67+
Ok(Self(owned_fd))
68+
}
69+
/// [`epoll_ctl`] with [`EpollOp::EpollCtlAdd`].
70+
pub fn add(&self,fd: impl AsFd, mut event: EpollEvent) -> Result<()> {
71+
epoll_ctl(self.0.as_raw_fd(),EpollOp::EpollCtlAdd,fd.as_fd().as_raw_fd(),&mut event)
72+
}
73+
/// [`epoll_ctl`] with [`EpollOp::EpollCtlDel`].
74+
pub fn delete(&self, fd: impl AsFd) -> Result<()> {
75+
epoll_ctl(self.0.as_raw_fd(),EpollOp::EpollCtlDel,fd.as_fd().as_raw_fd(),None)
76+
}
77+
/// [`epoll_ctl`] with [`EpollOp::EpollCtlMod`].
78+
pub fn modify(&self,fd: impl AsFd, event: &mut EpollEvent) -> Result<()> {
79+
epoll_ctl(self.0.as_raw_fd(),EpollOp::EpollCtlMod,fd.as_fd().as_raw_fd(),event)
80+
}
81+
/// [`epoll_wait`]
82+
pub fn wait(&self, events: &mut [EpollEvent], timeout: isize) -> Result<usize> {
83+
epoll_wait(self.0.as_raw_fd(),events,timeout)
84+
}
85+
}
86+
2987
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
3088
#[repr(i32)]
3189
#[non_exhaustive]

0 commit comments

Comments
 (0)