|
1 | 1 | use crate::network_poller::Interest; |
2 | | -use rustix::event::epoll::{ |
3 | | - add, create, delete, modify, wait, CreateFlags, EventData, EventFlags, |
4 | | - EventVec, |
| 2 | +use libc::{ |
| 3 | + epoll_create, epoll_ctl, epoll_event, epoll_wait, EPOLLET, EPOLLIN, |
| 4 | + EPOLLONESHOT, EPOLLOUT, EPOLL_CLOEXEC, EPOLL_CTL_ADD, EPOLL_CTL_DEL, |
| 5 | + EPOLL_CTL_MOD, |
5 | 6 | }; |
6 | | -use rustix::fd::{AsFd, OwnedFd}; |
7 | | -use rustix::io::Errno; |
| 7 | +use std::ffi::c_int; |
| 8 | +use std::io::Error; |
| 9 | +use std::os::fd::{AsRawFd, FromRawFd, OwnedFd}; |
| 10 | +use std::ptr::null_mut; |
8 | 11 |
|
9 | | -fn flags_for(interest: Interest) -> EventFlags { |
| 12 | +fn flags_for(interest: Interest) -> u32 { |
10 | 13 | let flags = match interest { |
11 | | - Interest::Read => EventFlags::IN, |
12 | | - Interest::Write => EventFlags::OUT, |
| 14 | + Interest::Read => EPOLLIN, |
| 15 | + Interest::Write => EPOLLOUT, |
13 | 16 | }; |
14 | 17 |
|
15 | | - flags | EventFlags::ET | EventFlags::ONESHOT |
| 18 | + (flags | EPOLLET | EPOLLONESHOT) as u32 |
16 | 19 | } |
17 | 20 |
|
18 | | -pub(crate) type Events = EventVec; |
| 21 | +pub(crate) type Event = epoll_event; |
19 | 22 |
|
20 | 23 | pub(crate) struct Poller { |
21 | 24 | fd: OwnedFd, |
22 | 25 | } |
23 | 26 |
|
24 | 27 | impl Poller { |
25 | 28 | pub(crate) fn new() -> Poller { |
26 | | - let fd = create(CreateFlags::CLOEXEC).expect("epoll_create() failed"); |
| 29 | + let fd = unsafe { epoll_create(EPOLL_CLOEXEC) }; |
27 | 30 |
|
28 | | - Poller { fd } |
| 31 | + if fd == -1 { |
| 32 | + panic!("epoll_create() failed"); |
| 33 | + } |
| 34 | + |
| 35 | + // Safety: we checked the file descriptor so at this point it's |
| 36 | + // guaranteed to be valid. |
| 37 | + Poller { fd: unsafe { OwnedFd::from_raw_fd(fd) } } |
29 | 38 | } |
30 | 39 |
|
31 | 40 | pub(crate) fn poll<'a>( |
32 | 41 | &self, |
33 | | - events: &'a mut Events, |
| 42 | + events: &'a mut Vec<Event>, |
34 | 43 | ) -> impl Iterator<Item = u64> + 'a { |
35 | | - match wait(&self.fd, events, -1) { |
36 | | - Ok(_) | Err(Errno::INTR) => {} |
37 | | - Err(_) => panic!("epoll_wait() failed"), |
| 44 | + let res = unsafe { |
| 45 | + epoll_wait( |
| 46 | + self.fd.as_raw_fd(), |
| 47 | + events.as_mut_ptr(), |
| 48 | + events.capacity() as _, |
| 49 | + -1, |
| 50 | + ) |
| 51 | + }; |
| 52 | + |
| 53 | + if res == -1 { |
| 54 | + panic!("epoll_wait() failed: {}", Error::last_os_error()); |
38 | 55 | } |
39 | 56 |
|
40 | | - events.iter().map(|e| e.data.u64()) |
| 57 | + // Safety: the above check ensures the length value is valid. |
| 58 | + unsafe { events.set_len(res as _) }; |
| 59 | + events.iter().map(|e| e.u64) |
41 | 60 | } |
42 | 61 |
|
43 | | - pub(crate) fn add(&self, id: u64, source: impl AsFd, interest: Interest) { |
44 | | - let data = EventData::new_u64(id); |
| 62 | + pub(crate) fn add( |
| 63 | + &self, |
| 64 | + id: u64, |
| 65 | + source: impl AsRawFd, |
| 66 | + interest: Interest, |
| 67 | + ) { |
| 68 | + let mut event = epoll_event { events: flags_for(interest), u64: id }; |
45 | 69 |
|
46 | | - add(&self.fd, source, data, flags_for(interest)) |
47 | | - .expect("epoll_ctl() failed"); |
| 70 | + self.ctl(EPOLL_CTL_ADD, source, Some(&mut event)); |
48 | 71 | } |
49 | 72 |
|
50 | 73 | pub(crate) fn modify( |
51 | 74 | &self, |
52 | 75 | id: u64, |
53 | | - source: impl AsFd, |
| 76 | + source: impl AsRawFd, |
54 | 77 | interest: Interest, |
55 | 78 | ) { |
56 | | - let data = EventData::new_u64(id); |
| 79 | + let mut event = epoll_event { events: flags_for(interest), u64: id }; |
| 80 | + |
| 81 | + self.ctl(EPOLL_CTL_MOD, source, Some(&mut event)); |
| 82 | + } |
57 | 83 |
|
58 | | - modify(&self.fd, source, data, flags_for(interest)) |
59 | | - .expect("epoll_ctl() failed"); |
| 84 | + pub(crate) fn delete(&self, source: impl AsRawFd) { |
| 85 | + self.ctl(EPOLL_CTL_DEL, source, None); |
60 | 86 | } |
61 | 87 |
|
62 | | - pub(crate) fn delete(&self, source: impl AsFd) { |
63 | | - delete(&self.fd, source).expect("epoll_ctl() failed"); |
| 88 | + fn ctl(&self, op: c_int, fd: impl AsRawFd, event: Option<&mut Event>) { |
| 89 | + let res = unsafe { |
| 90 | + epoll_ctl( |
| 91 | + self.fd.as_raw_fd(), |
| 92 | + op, |
| 93 | + fd.as_raw_fd(), |
| 94 | + event.map(|v| v as *mut _).unwrap_or_else(null_mut), |
| 95 | + ) |
| 96 | + }; |
| 97 | + |
| 98 | + if res == -1 { |
| 99 | + panic!("epoll_ctl() failed: {}", Error::last_os_error()); |
| 100 | + } |
64 | 101 | } |
65 | 102 | } |
0 commit comments