@@ -2,7 +2,7 @@ use crate::errno::Errno;
2
2
use crate :: Result ;
3
3
use libc:: { self , c_int} ;
4
4
use std:: mem;
5
- use std:: os:: unix:: io:: RawFd ;
5
+ use std:: os:: unix:: io:: { FromRawFd , RawFd , OwnedFd , AsFd , AsRawFd } ;
6
6
use std:: ptr;
7
7
8
8
libc_bitflags ! (
@@ -26,6 +26,64 @@ libc_bitflags!(
26
26
}
27
27
) ;
28
28
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 as isize);
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
+
29
87
#[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
30
88
#[ repr( i32 ) ]
31
89
#[ non_exhaustive]
0 commit comments