]> git.proxmox.com Git - pve-lxc-syscalld.git/blob - src/epoll.rs
blocking fixup, and actually recvmsg on recvmsg
[pve-lxc-syscalld.git] / src / epoll.rs
1 use std::convert::TryFrom;
2 use std::io;
3 use std::os::raw::c_int;
4 use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
5 use std::time::Duration;
6
7 use crate::error::io_err_other;
8 use crate::tools::Fd;
9
10 pub type EpollEvent = libc::epoll_event;
11
12 pub const EPOLLIN: u32 = libc::EPOLLIN as u32;
13 pub const EPOLLET: u32 = libc::EPOLLET as u32;
14 pub const EPOLLOUT: u32 = libc::EPOLLOUT as u32;
15 pub const EPOLLERR: u32 = libc::EPOLLERR as u32;
16 pub const EPOLLHUP: u32 = libc::EPOLLHUP as u32;
17
18 pub struct Epoll {
19 fd: Fd,
20 }
21
22 impl Epoll {
23 pub fn new() -> io::Result<Self> {
24 let fd = unsafe { Fd::from_raw_fd(c_try!(libc::epoll_create1(libc::EPOLL_CLOEXEC))) };
25 Ok(Self { fd })
26 }
27
28 pub fn add_file<T: AsRawFd>(&self, fd: &T, events: u32, data: u64) -> io::Result<()> {
29 self.add_fd(fd.as_raw_fd(), events, data)
30 }
31
32 pub fn modify_file<T: AsRawFd>(&self, fd: &T, events: u32, data: u64) -> io::Result<()> {
33 self.modify_fd(fd.as_raw_fd(), events, data)
34 }
35
36 pub fn remove_file<T: AsRawFd>(&self, fd: &T) -> io::Result<()> {
37 self.remove_fd(fd.as_raw_fd())
38 }
39
40 fn addmod_fd(&self, op: c_int, fd: RawFd, events: u32, data: u64) -> io::Result<()> {
41 let mut events = libc::epoll_event {
42 events,
43 r#u64: data,
44 };
45 c_try!(unsafe { libc::epoll_ctl(self.fd.as_raw_fd(), op, fd, &mut events) });
46 Ok(())
47 }
48
49 pub fn add_fd(&self, fd: RawFd, events: u32, data: u64) -> io::Result<()> {
50 self.addmod_fd(libc::EPOLL_CTL_ADD, fd, events, data)
51 }
52
53 pub fn modify_fd(&self, fd: RawFd, events: u32, data: u64) -> io::Result<()> {
54 self.addmod_fd(libc::EPOLL_CTL_MOD, fd, events, data)
55 }
56
57 pub fn remove_fd(&self, fd: RawFd) -> io::Result<()> {
58 c_try!(unsafe {
59 libc::epoll_ctl(
60 self.fd.as_raw_fd(),
61 libc::EPOLL_CTL_DEL,
62 fd,
63 std::ptr::null_mut(),
64 )
65 });
66 Ok(())
67 }
68
69 pub fn wait(
70 &self,
71 event_buf: &mut [EpollEvent],
72 timeout: Option<Duration>,
73 ) -> io::Result<usize> {
74 let millis = timeout
75 .map(|t| c_int::try_from(t.as_millis()))
76 .transpose()
77 .map_err(io_err_other)?
78 .unwrap_or(-1);
79 let epfd = self.fd.as_raw_fd();
80 let buf_len = c_int::try_from(event_buf.len()).map_err(io_err_other)?;
81 let rc = c_try!(unsafe { libc::epoll_wait(epfd, event_buf.as_mut_ptr(), buf_len, millis) });
82 Ok(rc as usize)
83 }
84 }