1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use std::{io, os::unix::io::RawFd};
use super::{Interest, Mode, PollEvent, Readiness, Token};
use crate::no_nix_err;
use nix::sys::epoll;
pub struct Epoll {
epoll_fd: RawFd,
}
fn make_flags(interest: Interest, mode: Mode) -> epoll::EpollFlags {
let mut flags = match interest {
Interest::Readable => epoll::EpollFlags::EPOLLIN,
Interest::Writable => epoll::EpollFlags::EPOLLOUT,
Interest::Both => epoll::EpollFlags::EPOLLIN | epoll::EpollFlags::EPOLLOUT,
};
match mode {
Mode::Level => { }
Mode::Edge => flags |= epoll::EpollFlags::EPOLLET,
Mode::OneShot => flags |= epoll::EpollFlags::EPOLLONESHOT,
}
flags
}
fn flags_to_readiness(flags: epoll::EpollFlags) -> Readiness {
Readiness {
readable: flags.contains(epoll::EpollFlags::EPOLLIN),
writable: flags.contains(epoll::EpollFlags::EPOLLOUT),
error: flags.contains(epoll::EpollFlags::EPOLLERR),
}
}
impl Epoll {
pub(crate) fn new() -> io::Result<Epoll> {
let epoll_fd =
epoll::epoll_create1(epoll::EpollCreateFlags::EPOLL_CLOEXEC).map_err(no_nix_err)?;
Ok(Epoll { epoll_fd })
}
pub(crate) fn poll(
&mut self,
timeout: Option<std::time::Duration>,
) -> io::Result<Vec<PollEvent>> {
let mut buffer = [epoll::EpollEvent::empty(); 32];
let timeout = timeout.map(|d| d.as_millis() as isize).unwrap_or(-1);
let n_ready = epoll::epoll_wait(self.epoll_fd, &mut buffer, timeout).map_err(no_nix_err)?;
let events = buffer
.iter()
.take(n_ready)
.map(|event| PollEvent {
readiness: flags_to_readiness(event.events()),
token: Token::from_u64(event.data()),
})
.collect();
Ok(events)
}
pub fn register(
&mut self,
fd: RawFd,
interest: Interest,
mode: Mode,
token: Token,
) -> io::Result<()> {
let mut event = epoll::EpollEvent::new(make_flags(interest, mode), token.to_u64());
epoll::epoll_ctl(self.epoll_fd, epoll::EpollOp::EpollCtlAdd, fd, &mut event)
.map_err(no_nix_err)
}
pub fn reregister(
&mut self,
fd: RawFd,
interest: Interest,
mode: Mode,
token: Token,
) -> io::Result<()> {
let mut event = epoll::EpollEvent::new(make_flags(interest, mode), token.to_u64());
epoll::epoll_ctl(self.epoll_fd, epoll::EpollOp::EpollCtlMod, fd, &mut event)
.map_err(no_nix_err)
}
pub fn unregister(&mut self, fd: RawFd) -> io::Result<()> {
epoll::epoll_ctl(self.epoll_fd, epoll::EpollOp::EpollCtlDel, fd, None).map_err(no_nix_err)
}
}
impl Drop for Epoll {
fn drop(&mut self) {
let _ = nix::unistd::close(self.epoll_fd);
}
}