@@ -2,8 +2,7 @@ use crate::errno::Errno;
22use crate :: Result ;
33use libc:: { self , c_int} ;
44use std:: mem;
5- use std:: os:: unix:: io:: RawFd ;
6- use std:: ptr;
5+ use std:: os:: unix:: io:: { FromRawFd , RawFd , OwnedFd , AsFd , AsRawFd } ;
76
87libc_bitflags ! (
98 pub struct EpollFlags : c_int {
@@ -70,20 +69,126 @@ impl EpollEvent {
7069 }
7170}
7271
72+ /// A safe wrapper around [`epoll`](https://man7.org/linux/man-pages/man7/epoll.7.html).
73+ /// ```
74+ /// # use nix::sys::{epoll::{Epoll, EpollEvent, EpollFlags, EpollCreateFlags}, eventfd::{eventfd, EfdFlags}};
75+ /// # use nix::unistd::write;
76+ /// # use std::os::unix::io::{OwnedFd, FromRawFd, AsRawFd, AsFd};
77+ /// # use std::time::{Instant, Duration};
78+ /// # fn main() -> nix::Result<()> {
79+ /// const DATA: u64 = 17;
80+ /// const MILLIS: u64 = 100;
81+ ///
82+ /// // Create epoll
83+ /// let epoll = Epoll::new(EpollCreateFlags::empty())?;
84+ ///
85+ /// // Create eventfd & Add event
86+ /// let eventfd = unsafe { OwnedFd::from_raw_fd(eventfd(0, EfdFlags::empty())?) };
87+ /// epoll.add(&eventfd, EpollEvent::new(EpollFlags::EPOLLIN,DATA))?;
88+ ///
89+ /// // Arm eventfd & Time wait
90+ /// write(eventfd.as_raw_fd(), &1u64.to_ne_bytes())?;
91+ /// let now = Instant::now();
92+ ///
93+ /// // Wait on event
94+ /// let mut events = [EpollEvent::empty()];
95+ /// epoll.wait(&mut events, MILLIS as isize)?;
96+ ///
97+ /// // Assert data correct & timeout didn't occur
98+ /// assert_eq!(events[0].data(), DATA);
99+ /// assert!(now.elapsed() < Duration::from_millis(MILLIS));
100+ /// # Ok(())
101+ /// # }
102+ /// ```
103+ #[ derive( Debug ) ]
104+ pub struct Epoll ( pub OwnedFd ) ;
105+ impl Epoll {
106+ /// Creates a new epoll instance and returns a file descriptor referring to that instance.
107+ ///
108+ /// [`epoll_create1`](https://man7.org/linux/man-pages/man2/epoll_create1.2.html).
109+ pub fn new ( flags : EpollCreateFlags ) -> Result < Self > {
110+ let res = unsafe { libc:: epoll_create1 ( flags. bits ( ) ) } ;
111+ let fd = Errno :: result ( res) ?;
112+ let owned_fd = unsafe { OwnedFd :: from_raw_fd ( fd) } ;
113+ Ok ( Self ( owned_fd) )
114+ }
115+ /// Add an entry to the interest list of the epoll file descriptor for
116+ /// specified in events.
117+ ///
118+ /// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html) with `EPOLL_CTL_ADD`.
119+ pub fn add < Fd : AsFd > ( & self , fd : Fd , mut event : EpollEvent ) -> Result < ( ) > {
120+ self . epoll_ctl ( EpollOp :: EpollCtlAdd , fd, & mut event)
121+ }
122+ /// Remove (deregister) the target file descriptor `fd` from the interest list.
123+ ///
124+ /// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html) with `EPOLL_CTL_DEL` .
125+ pub fn delete < Fd : AsFd > ( & self , fd : Fd ) -> Result < ( ) > {
126+ self . epoll_ctl ( EpollOp :: EpollCtlDel , fd, None )
127+ }
128+ /// Change the settings associated with `fd` in the interest list to the new settings specified
129+ /// in `event`.
130+ ///
131+ /// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html) with `EPOLL_CTL_MOD`.
132+ pub fn modify < Fd : AsFd > ( & self , fd : Fd , event : & mut EpollEvent ) -> Result < ( ) > {
133+ self . epoll_ctl ( EpollOp :: EpollCtlMod , fd, event)
134+ }
135+ /// Waits for I/O events, blocking the calling thread if no events are currently available.
136+ /// (This can be thought of as fetching items from the ready list of the epoll instance.)
137+ ///
138+ /// [`epoll_wait`](https://man7.org/linux/man-pages/man2/epoll_wait.2.html)
139+ pub fn wait ( & self , events : & mut [ EpollEvent ] , timeout : isize ) -> Result < usize > {
140+ let res = unsafe {
141+ libc:: epoll_wait (
142+ self . 0 . as_raw_fd ( ) ,
143+ events. as_mut_ptr ( ) as * mut libc:: epoll_event ,
144+ events. len ( ) as c_int ,
145+ timeout as c_int ,
146+ )
147+ } ;
148+
149+ Errno :: result ( res) . map ( |r| r as usize )
150+ }
151+ /// This system call is used to add, modify, or remove entries in the interest list of the epoll
152+ /// instance referred to by `self`. It requests that the operation `op` be performed for the
153+ /// target file descriptor, `fd`.
154+ ///
155+ /// When possible prefer [`Epoll::add`], [`Epoll::delete`] and [`Epoll::modify`].
156+ ///
157+ /// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html)
158+ fn epoll_ctl < ' a , Fd : AsFd , T > (
159+ & self ,
160+ op : EpollOp ,
161+ fd : Fd ,
162+ event : T ,
163+ ) -> Result < ( ) >
164+ where
165+ T : Into < Option < & ' a mut EpollEvent > > ,
166+ {
167+ let event: Option < & mut EpollEvent > = event. into ( ) ;
168+ let ptr = event. map ( |x|& mut x. event as * mut libc:: epoll_event ) . unwrap_or ( std:: ptr:: null_mut ( ) ) ;
169+ unsafe {
170+ Errno :: result ( libc:: epoll_ctl ( self . 0 . as_raw_fd ( ) , op as c_int , fd. as_fd ( ) . as_raw_fd ( ) , ptr) ) . map ( drop)
171+ }
172+ }
173+ }
174+
175+ #[ deprecated( since = "0.27.0" , note = "Use Epoll::new() instead" ) ]
73176#[ inline]
74177pub fn epoll_create ( ) -> Result < RawFd > {
75178 let res = unsafe { libc:: epoll_create ( 1024 ) } ;
76179
77180 Errno :: result ( res)
78181}
79182
183+ #[ deprecated( since = "0.27.0" , note = "Use Epoll::new() instead" ) ]
80184#[ inline]
81185pub fn epoll_create1 ( flags : EpollCreateFlags ) -> Result < RawFd > {
82186 let res = unsafe { libc:: epoll_create1 ( flags. bits ( ) ) } ;
83187
84188 Errno :: result ( res)
85189}
86190
191+ #[ deprecated( since = "0.27.0" , note = "Use Epoll::epoll_ctl() instead" ) ]
87192#[ inline]
88193pub fn epoll_ctl < ' a , T > (
89194 epfd : RawFd ,
@@ -102,13 +207,14 @@ where
102207 if let Some ( ref mut event) = event {
103208 libc:: epoll_ctl ( epfd, op as c_int , fd, & mut event. event )
104209 } else {
105- libc:: epoll_ctl ( epfd, op as c_int , fd, ptr:: null_mut ( ) )
210+ libc:: epoll_ctl ( epfd, op as c_int , fd, std :: ptr:: null_mut ( ) )
106211 }
107212 } ;
108213 Errno :: result ( res) . map ( drop)
109214 }
110215}
111216
217+ #[ deprecated( since = "0.27.0" , note = "Use Epoll::wait() instead" ) ]
112218#[ inline]
113219pub fn epoll_wait (
114220 epfd : RawFd ,
@@ -125,4 +231,4 @@ pub fn epoll_wait(
125231 } ;
126232
127233 Errno :: result ( res) . map ( |r| r as usize )
128- }
234+ }
0 commit comments