13da5c369Sopenharmony_ciuse crate::errno::Errno;
23da5c369Sopenharmony_ciuse crate::Result;
33da5c369Sopenharmony_ciuse libc::{self, c_int};
43da5c369Sopenharmony_ciuse std::mem;
53da5c369Sopenharmony_ciuse std::os::unix::io::RawFd;
63da5c369Sopenharmony_ciuse std::ptr;
73da5c369Sopenharmony_ci
83da5c369Sopenharmony_cilibc_bitflags!(
93da5c369Sopenharmony_ci    pub struct EpollFlags: c_int {
103da5c369Sopenharmony_ci        EPOLLIN;
113da5c369Sopenharmony_ci        EPOLLPRI;
123da5c369Sopenharmony_ci        EPOLLOUT;
133da5c369Sopenharmony_ci        EPOLLRDNORM;
143da5c369Sopenharmony_ci        EPOLLRDBAND;
153da5c369Sopenharmony_ci        EPOLLWRNORM;
163da5c369Sopenharmony_ci        EPOLLWRBAND;
173da5c369Sopenharmony_ci        EPOLLMSG;
183da5c369Sopenharmony_ci        EPOLLERR;
193da5c369Sopenharmony_ci        EPOLLHUP;
203da5c369Sopenharmony_ci        EPOLLRDHUP;
213da5c369Sopenharmony_ci        EPOLLEXCLUSIVE;
223da5c369Sopenharmony_ci        #[cfg(not(target_arch = "mips"))]
233da5c369Sopenharmony_ci        EPOLLWAKEUP;
243da5c369Sopenharmony_ci        EPOLLONESHOT;
253da5c369Sopenharmony_ci        EPOLLET;
263da5c369Sopenharmony_ci    }
273da5c369Sopenharmony_ci);
283da5c369Sopenharmony_ci
293da5c369Sopenharmony_ci#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
303da5c369Sopenharmony_ci#[repr(i32)]
313da5c369Sopenharmony_ci#[non_exhaustive]
323da5c369Sopenharmony_cipub enum EpollOp {
333da5c369Sopenharmony_ci    EpollCtlAdd = libc::EPOLL_CTL_ADD,
343da5c369Sopenharmony_ci    EpollCtlDel = libc::EPOLL_CTL_DEL,
353da5c369Sopenharmony_ci    EpollCtlMod = libc::EPOLL_CTL_MOD,
363da5c369Sopenharmony_ci}
373da5c369Sopenharmony_ci
383da5c369Sopenharmony_cilibc_bitflags! {
393da5c369Sopenharmony_ci    pub struct EpollCreateFlags: c_int {
403da5c369Sopenharmony_ci        EPOLL_CLOEXEC;
413da5c369Sopenharmony_ci    }
423da5c369Sopenharmony_ci}
433da5c369Sopenharmony_ci
443da5c369Sopenharmony_ci#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
453da5c369Sopenharmony_ci#[repr(transparent)]
463da5c369Sopenharmony_cipub struct EpollEvent {
473da5c369Sopenharmony_ci    event: libc::epoll_event,
483da5c369Sopenharmony_ci}
493da5c369Sopenharmony_ci
503da5c369Sopenharmony_ciimpl EpollEvent {
513da5c369Sopenharmony_ci    pub fn new(events: EpollFlags, data: u64) -> Self {
523da5c369Sopenharmony_ci        EpollEvent {
533da5c369Sopenharmony_ci            event: libc::epoll_event {
543da5c369Sopenharmony_ci                events: events.bits() as u32,
553da5c369Sopenharmony_ci                u64: data,
563da5c369Sopenharmony_ci            },
573da5c369Sopenharmony_ci        }
583da5c369Sopenharmony_ci    }
593da5c369Sopenharmony_ci
603da5c369Sopenharmony_ci    pub fn empty() -> Self {
613da5c369Sopenharmony_ci        unsafe { mem::zeroed::<EpollEvent>() }
623da5c369Sopenharmony_ci    }
633da5c369Sopenharmony_ci
643da5c369Sopenharmony_ci    pub fn events(&self) -> EpollFlags {
653da5c369Sopenharmony_ci        EpollFlags::from_bits(self.event.events as c_int).unwrap()
663da5c369Sopenharmony_ci    }
673da5c369Sopenharmony_ci
683da5c369Sopenharmony_ci    pub fn data(&self) -> u64 {
693da5c369Sopenharmony_ci        self.event.u64
703da5c369Sopenharmony_ci    }
713da5c369Sopenharmony_ci}
723da5c369Sopenharmony_ci
733da5c369Sopenharmony_ci#[inline]
743da5c369Sopenharmony_cipub fn epoll_create() -> Result<RawFd> {
753da5c369Sopenharmony_ci    let res = unsafe { libc::epoll_create(1024) };
763da5c369Sopenharmony_ci
773da5c369Sopenharmony_ci    Errno::result(res)
783da5c369Sopenharmony_ci}
793da5c369Sopenharmony_ci
803da5c369Sopenharmony_ci#[inline]
813da5c369Sopenharmony_cipub fn epoll_create1(flags: EpollCreateFlags) -> Result<RawFd> {
823da5c369Sopenharmony_ci    let res = unsafe { libc::epoll_create1(flags.bits()) };
833da5c369Sopenharmony_ci
843da5c369Sopenharmony_ci    Errno::result(res)
853da5c369Sopenharmony_ci}
863da5c369Sopenharmony_ci
873da5c369Sopenharmony_ci#[inline]
883da5c369Sopenharmony_cipub fn epoll_ctl<'a, T>(
893da5c369Sopenharmony_ci    epfd: RawFd,
903da5c369Sopenharmony_ci    op: EpollOp,
913da5c369Sopenharmony_ci    fd: RawFd,
923da5c369Sopenharmony_ci    event: T,
933da5c369Sopenharmony_ci) -> Result<()>
943da5c369Sopenharmony_ciwhere
953da5c369Sopenharmony_ci    T: Into<Option<&'a mut EpollEvent>>,
963da5c369Sopenharmony_ci{
973da5c369Sopenharmony_ci    let mut event: Option<&mut EpollEvent> = event.into();
983da5c369Sopenharmony_ci    if event.is_none() && op != EpollOp::EpollCtlDel {
993da5c369Sopenharmony_ci        Err(Errno::EINVAL)
1003da5c369Sopenharmony_ci    } else {
1013da5c369Sopenharmony_ci        let res = unsafe {
1023da5c369Sopenharmony_ci            if let Some(ref mut event) = event {
1033da5c369Sopenharmony_ci                libc::epoll_ctl(epfd, op as c_int, fd, &mut event.event)
1043da5c369Sopenharmony_ci            } else {
1053da5c369Sopenharmony_ci                libc::epoll_ctl(epfd, op as c_int, fd, ptr::null_mut())
1063da5c369Sopenharmony_ci            }
1073da5c369Sopenharmony_ci        };
1083da5c369Sopenharmony_ci        Errno::result(res).map(drop)
1093da5c369Sopenharmony_ci    }
1103da5c369Sopenharmony_ci}
1113da5c369Sopenharmony_ci
1123da5c369Sopenharmony_ci#[inline]
1133da5c369Sopenharmony_cipub fn epoll_wait(
1143da5c369Sopenharmony_ci    epfd: RawFd,
1153da5c369Sopenharmony_ci    events: &mut [EpollEvent],
1163da5c369Sopenharmony_ci    timeout_ms: isize,
1173da5c369Sopenharmony_ci) -> Result<usize> {
1183da5c369Sopenharmony_ci    let res = unsafe {
1193da5c369Sopenharmony_ci        libc::epoll_wait(
1203da5c369Sopenharmony_ci            epfd,
1213da5c369Sopenharmony_ci            events.as_mut_ptr() as *mut libc::epoll_event,
1223da5c369Sopenharmony_ci            events.len() as c_int,
1233da5c369Sopenharmony_ci            timeout_ms as c_int,
1243da5c369Sopenharmony_ci        )
1253da5c369Sopenharmony_ci    };
1263da5c369Sopenharmony_ci
1273da5c369Sopenharmony_ci    Errno::result(res).map(|r| r as usize)
1283da5c369Sopenharmony_ci}
129