| use crate::errno::Errno; | 
 | pub use crate::poll_timeout::PollTimeout as EpollTimeout; | 
 | use crate::Result; | 
 | use libc::{self, c_int}; | 
 | use std::mem; | 
 | use std::os::unix::io::{AsFd, AsRawFd, FromRawFd, OwnedFd, RawFd}; | 
 |  | 
 | libc_bitflags!( | 
 |     pub struct EpollFlags: c_int { | 
 |         EPOLLIN; | 
 |         EPOLLPRI; | 
 |         EPOLLOUT; | 
 |         EPOLLRDNORM; | 
 |         EPOLLRDBAND; | 
 |         EPOLLWRNORM; | 
 |         EPOLLWRBAND; | 
 |         EPOLLMSG; | 
 |         EPOLLERR; | 
 |         EPOLLHUP; | 
 |         EPOLLRDHUP; | 
 |         EPOLLEXCLUSIVE; | 
 |         #[cfg(not(target_arch = "mips"))] | 
 |         EPOLLWAKEUP; | 
 |         EPOLLONESHOT; | 
 |         EPOLLET; | 
 |     } | 
 | ); | 
 |  | 
 | #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] | 
 | #[repr(i32)] | 
 | #[non_exhaustive] | 
 | pub enum EpollOp { | 
 |     EpollCtlAdd = libc::EPOLL_CTL_ADD, | 
 |     EpollCtlDel = libc::EPOLL_CTL_DEL, | 
 |     EpollCtlMod = libc::EPOLL_CTL_MOD, | 
 | } | 
 |  | 
 | libc_bitflags! { | 
 |     pub struct EpollCreateFlags: c_int { | 
 |         EPOLL_CLOEXEC; | 
 |     } | 
 | } | 
 |  | 
 | #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] | 
 | #[repr(transparent)] | 
 | pub struct EpollEvent { | 
 |     event: libc::epoll_event, | 
 | } | 
 |  | 
 | impl EpollEvent { | 
 |     pub fn new(events: EpollFlags, data: u64) -> Self { | 
 |         EpollEvent { | 
 |             event: libc::epoll_event { | 
 |                 events: events.bits() as u32, | 
 |                 u64: data, | 
 |             }, | 
 |         } | 
 |     } | 
 |  | 
 |     pub fn empty() -> Self { | 
 |         unsafe { mem::zeroed::<EpollEvent>() } | 
 |     } | 
 |  | 
 |     pub fn events(&self) -> EpollFlags { | 
 |         EpollFlags::from_bits(self.event.events as c_int).unwrap() | 
 |     } | 
 |  | 
 |     pub fn data(&self) -> u64 { | 
 |         self.event.u64 | 
 |     } | 
 | } | 
 |  | 
 | /// A safe wrapper around [`epoll`](https://man7.org/linux/man-pages/man7/epoll.7.html). | 
 | /// ``` | 
 | /// # use nix::sys::{epoll::{EpollTimeout, Epoll, EpollEvent, EpollFlags, EpollCreateFlags}, eventfd::{EventFd, EfdFlags}}; | 
 | /// # use nix::unistd::write; | 
 | /// # use std::os::unix::io::{OwnedFd, FromRawFd, AsFd}; | 
 | /// # use std::time::{Instant, Duration}; | 
 | /// # fn main() -> nix::Result<()> { | 
 | /// const DATA: u64 = 17; | 
 | /// const MILLIS: u8 = 100; | 
 | /// | 
 | /// // Create epoll | 
 | /// let epoll = Epoll::new(EpollCreateFlags::empty())?; | 
 | /// | 
 | /// // Create eventfd & Add event | 
 | /// let eventfd = EventFd::new()?; | 
 | /// epoll.add(&eventfd, EpollEvent::new(EpollFlags::EPOLLIN,DATA))?; | 
 | /// | 
 | /// // Arm eventfd & Time wait | 
 | /// eventfd.arm()?; | 
 | /// let now = Instant::now(); | 
 | /// | 
 | /// // Wait on event | 
 | /// let mut events = [EpollEvent::empty()]; | 
 | /// epoll.wait(&mut events, MILLIS)?; | 
 | /// | 
 | /// // Assert data correct & timeout didn't occur | 
 | /// assert_eq!(events[0].data(), DATA); | 
 | /// assert!(now.elapsed().as_millis() < MILLIS.into()); | 
 | /// # Ok(()) | 
 | /// # } | 
 | /// ``` | 
 | #[derive(Debug)] | 
 | pub struct Epoll(pub OwnedFd); | 
 | impl Epoll { | 
 |     /// Creates a new epoll instance and returns a file descriptor referring to that instance. | 
 |     /// | 
 |     /// [`epoll_create1`](https://man7.org/linux/man-pages/man2/epoll_create1.2.html). | 
 |     pub fn new(flags: EpollCreateFlags) -> Result<Self> { | 
 |         let res = unsafe { libc::epoll_create1(flags.bits()) }; | 
 |         let fd = Errno::result(res)?; | 
 |         let owned_fd = unsafe { OwnedFd::from_raw_fd(fd) }; | 
 |         Ok(Self(owned_fd)) | 
 |     } | 
 |     /// Add an entry to the interest list of the epoll file descriptor for | 
 |     /// specified in events. | 
 |     /// | 
 |     /// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html) with `EPOLL_CTL_ADD`. | 
 |     pub fn add<Fd: AsFd>(&self, fd: Fd, mut event: EpollEvent) -> Result<()> { | 
 |         self.epoll_ctl(EpollOp::EpollCtlAdd, fd, &mut event) | 
 |     } | 
 |     /// Remove (deregister) the target file descriptor `fd` from the interest list. | 
 |     /// | 
 |     /// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html) with `EPOLL_CTL_DEL` . | 
 |     pub fn delete<Fd: AsFd>(&self, fd: Fd) -> Result<()> { | 
 |         self.epoll_ctl(EpollOp::EpollCtlDel, fd, None) | 
 |     } | 
 |     /// Change the settings associated with `fd` in the interest list to the new settings specified | 
 |     /// in `event`. | 
 |     /// | 
 |     /// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html) with `EPOLL_CTL_MOD`. | 
 |     pub fn modify<Fd: AsFd>( | 
 |         &self, | 
 |         fd: Fd, | 
 |         event: &mut EpollEvent, | 
 |     ) -> Result<()> { | 
 |         self.epoll_ctl(EpollOp::EpollCtlMod, fd, event) | 
 |     } | 
 |     /// Waits for I/O events, blocking the calling thread if no events are currently available. | 
 |     /// (This can be thought of as fetching items from the ready list of the epoll instance.) | 
 |     /// | 
 |     /// [`epoll_wait`](https://man7.org/linux/man-pages/man2/epoll_wait.2.html) | 
 |     pub fn wait<T: Into<EpollTimeout>>( | 
 |         &self, | 
 |         events: &mut [EpollEvent], | 
 |         timeout: T, | 
 |     ) -> Result<usize> { | 
 |         let res = unsafe { | 
 |             libc::epoll_wait( | 
 |                 self.0.as_raw_fd(), | 
 |                 events.as_mut_ptr().cast(), | 
 |                 events.len() as c_int, | 
 |                 timeout.into().into(), | 
 |             ) | 
 |         }; | 
 |  | 
 |         Errno::result(res).map(|r| r as usize) | 
 |     } | 
 |     /// This system call is used to add, modify, or remove entries in the interest list of the epoll | 
 |     /// instance referred to by `self`. It requests that the operation `op` be performed for the | 
 |     /// target file descriptor, `fd`. | 
 |     /// | 
 |     /// When possible prefer [`Epoll::add`], [`Epoll::delete`] and [`Epoll::modify`]. | 
 |     /// | 
 |     /// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html) | 
 |     fn epoll_ctl<'a, Fd: AsFd, T>( | 
 |         &self, | 
 |         op: EpollOp, | 
 |         fd: Fd, | 
 |         event: T, | 
 |     ) -> Result<()> | 
 |     where | 
 |         T: Into<Option<&'a mut EpollEvent>>, | 
 |     { | 
 |         let event: Option<&mut EpollEvent> = event.into(); | 
 |         let ptr = event | 
 |             .map(|x| &mut x.event as *mut libc::epoll_event) | 
 |             .unwrap_or(std::ptr::null_mut()); | 
 |         unsafe { | 
 |             Errno::result(libc::epoll_ctl( | 
 |                 self.0.as_raw_fd(), | 
 |                 op as c_int, | 
 |                 fd.as_fd().as_raw_fd(), | 
 |                 ptr, | 
 |             )) | 
 |             .map(drop) | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | #[deprecated(since = "0.27.0", note = "Use Epoll::new() instead")] | 
 | #[inline] | 
 | pub fn epoll_create() -> Result<RawFd> { | 
 |     let res = unsafe { libc::epoll_create(1024) }; | 
 |  | 
 |     Errno::result(res) | 
 | } | 
 |  | 
 | #[deprecated(since = "0.27.0", note = "Use Epoll::new() instead")] | 
 | #[inline] | 
 | pub fn epoll_create1(flags: EpollCreateFlags) -> Result<RawFd> { | 
 |     let res = unsafe { libc::epoll_create1(flags.bits()) }; | 
 |  | 
 |     Errno::result(res) | 
 | } | 
 |  | 
 | #[deprecated(since = "0.27.0", note = "Use Epoll::epoll_ctl() instead")] | 
 | #[inline] | 
 | pub fn epoll_ctl<'a, T>( | 
 |     epfd: RawFd, | 
 |     op: EpollOp, | 
 |     fd: RawFd, | 
 |     event: T, | 
 | ) -> Result<()> | 
 | where | 
 |     T: Into<Option<&'a mut EpollEvent>>, | 
 | { | 
 |     let mut event: Option<&mut EpollEvent> = event.into(); | 
 |     if event.is_none() && op != EpollOp::EpollCtlDel { | 
 |         Err(Errno::EINVAL) | 
 |     } else { | 
 |         let res = unsafe { | 
 |             if let Some(ref mut event) = event { | 
 |                 libc::epoll_ctl(epfd, op as c_int, fd, &mut event.event) | 
 |             } else { | 
 |                 libc::epoll_ctl(epfd, op as c_int, fd, std::ptr::null_mut()) | 
 |             } | 
 |         }; | 
 |         Errno::result(res).map(drop) | 
 |     } | 
 | } | 
 |  | 
 | #[deprecated(since = "0.27.0", note = "Use Epoll::wait() instead")] | 
 | #[inline] | 
 | pub fn epoll_wait( | 
 |     epfd: RawFd, | 
 |     events: &mut [EpollEvent], | 
 |     timeout_ms: isize, | 
 | ) -> Result<usize> { | 
 |     let res = unsafe { | 
 |         libc::epoll_wait( | 
 |             epfd, | 
 |             events.as_mut_ptr().cast(), | 
 |             events.len() as c_int, | 
 |             timeout_ms as c_int, | 
 |         ) | 
 |     }; | 
 |  | 
 |     Errno::result(res).map(|r| r as usize) | 
 | } |