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