From d4e71a780e7a182267baefeef11575dfd92d1d87 Mon Sep 17 00:00:00 2001 From: overweight Date: Thu, 9 Dec 2021 20:52:32 +0800 Subject: [PATCH] rework event poll --- src/event/src/lib.rs | 24 ++++++++- src/event/src/{sys => poll}/epoll.rs | 75 +++++++++++++++++----------- src/event/src/poll/mod.rs | 47 +++++++++++++++++ src/event/src/sys/mod.rs | 43 ---------------- 4 files changed, 115 insertions(+), 74 deletions(-) rename src/event/src/{sys => poll}/epoll.rs (44%) create mode 100644 src/event/src/poll/mod.rs delete mode 100644 src/event/src/sys/mod.rs diff --git a/src/event/src/lib.rs b/src/event/src/lib.rs index e79c79d9..0c047083 100644 --- a/src/event/src/lib.rs +++ b/src/event/src/lib.rs @@ -1 +1,23 @@ -mod sys; +//pub mod events; +pub mod poll; +//pub mod sources; + +#[allow(unused_macros)] +#[macro_export] +macro_rules! syscall { + ($fn: ident ( $($arg: expr),* $(,)* ) ) => {{ + let res = unsafe { libc::$fn($($arg, )*) }; + if res == -1 { + Err(std::io::Error::last_os_error()) + } else { + Ok(res) + } + }}; +} + +#[cfg(test)] +mod test { + #[cfg(unix)] + #[test] + fn build() {} +} diff --git a/src/event/src/sys/epoll.rs b/src/event/src/poll/epoll.rs similarity index 44% rename from src/event/src/sys/epoll.rs rename to src/event/src/poll/epoll.rs index ef6caaf1..8811efe9 100644 --- a/src/event/src/sys/epoll.rs +++ b/src/event/src/poll/epoll.rs @@ -1,53 +1,59 @@ -use std::{io, os::unix::io::RawFd, ptr, sync::atomic::{AtomicUsize, Ordering::Relaxed}}; use libc::{epoll_event, EPOLL_CLOEXEC, EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD}; +use std::os::unix::io::{AsRawFd, RawFd}; +use std::sync::atomic::{AtomicUsize, Ordering::Relaxed}; +use std::{io, ptr}; -#[allow(unused_macros)] -macro_rules! syscall { - ($fn: ident ( $($arg: expr),* $(,)* ) ) => {{ - let res = unsafe { libc::$fn($($arg, )*) }; - if res == -1 { - Err(std::io::Error::last_os_error()) - } else { - Ok(res) - } - }}; -} +use crate::syscall; + +const LOWEST_FD: libc::c_int = 3; -#[derive(Debug)] -pub struct Epoll { +#[derive(Debug, Default)] +pub(crate) struct Epoll { epoll_fd: RawFd, n_sources: AtomicUsize, } impl Epoll { - pub fn new() -> io::Result { - syscall!(epoll_create1(EPOLL_CLOEXEC)).map( | ep | - Epoll { epoll_fd: ep, - n_sources: AtomicUsize::new(0), + pub(crate) fn new() -> io::Result { + syscall!(epoll_create1(EPOLL_CLOEXEC)).map(|ep| Epoll { + epoll_fd: ep, + n_sources: AtomicUsize::new(0), }) } - pub fn poll(&mut self, timeout: Option) -> io::Result> { + pub(crate) fn try_clone(&self) -> io::Result { + syscall!(fcntl(self.epoll_fd, libc::F_DUPFD_CLOEXEC, LOWEST_FD)).map(|ep| Epoll { + epoll_fd: ep, + n_sources: AtomicUsize::new(0), + }) + } + + pub(crate) fn poll( + &mut self, + timeout: Option, + ) -> io::Result> { let mut events = Vec::::with_capacity(self.n_sources.load(Relaxed)); let _n_ready = syscall!(epoll_wait( self.epoll_fd, events.as_mut_ptr(), events.capacity() as i32, - timeout.map(|to| to.as_millis() as libc::c_int).unwrap_or(-1), + timeout + .map(|to| to.as_millis() as libc::c_int) + .unwrap_or(-1), )); Ok(events) } - - pub fn register(&mut self, fd: RawFd, event: &mut epoll_event) -> io::Result<()> { + + pub(crate) fn register(&mut self, fd: RawFd, event: &mut epoll_event) -> io::Result<()> { self.n_sources.fetch_add(1, Relaxed); syscall!(epoll_ctl(self.epoll_fd, EPOLL_CTL_ADD, fd, event)).map(|_| ()) } - pub fn reregister(&mut self, fd: RawFd, event: &mut epoll_event) -> io::Result<()> { + pub(crate) fn reregister(&mut self, fd: RawFd, event: &mut epoll_event) -> io::Result<()> { syscall!(epoll_ctl(self.epoll_fd, EPOLL_CTL_MOD, fd, event)).map(|_| ()) } - - pub fn unregister(&mut self, fd: RawFd) -> io::Result<()> { + + pub(crate) fn unregister(&mut self, fd: RawFd) -> io::Result<()> { self.n_sources.fetch_sub(1, Relaxed); syscall!(epoll_ctl(self.epoll_fd, EPOLL_CTL_DEL, fd, ptr::null_mut())).map(|_| ()) } @@ -59,10 +65,16 @@ impl Drop for Epoll { } } +impl AsRawFd for Epoll { + fn as_raw_fd(&self) -> RawFd { + self.epoll_fd + } +} + #[cfg(test)] mod test { - use libc::EPOLLIN; use super::Epoll; + use libc::EPOLLIN; #[cfg(unix)] #[test] @@ -74,8 +86,11 @@ mod test { #[test] fn epoll_add() { let mut poll = Epoll::new().unwrap(); - let mut events = libc::epoll_event {events: EPOLLIN as u32, u64: 0,}; - poll.register(poll.epoll_fd, &mut events); - poll.unregister(poll.epoll_fd); + let mut events = libc::epoll_event { + events: EPOLLIN as u32, + u64: 0, + }; + let _ = poll.register(poll.epoll_fd, &mut events); + let _ = poll.unregister(poll.epoll_fd); } -} \ No newline at end of file +} diff --git a/src/event/src/poll/mod.rs b/src/event/src/poll/mod.rs new file mode 100644 index 00000000..00125ca3 --- /dev/null +++ b/src/event/src/poll/mod.rs @@ -0,0 +1,47 @@ +mod epoll; + +use epoll::Epoll; +use libc::epoll_event; +use std::os::unix::{io::AsRawFd, io::RawFd}; +use std::{io, time}; + +#[derive(Debug, Default)] +pub struct Poll { + poller: Epoll, +} + +impl Poll { + pub fn new() -> io::Result { + Ok(Poll { + poller: Epoll::new()?, + }) + } + + pub fn try_clone(&self) -> io::Result { + Ok(Poll { + poller: self.poller.try_clone().unwrap(), + }) + } + + pub fn poll(&mut self, timeout: Option) -> io::Result> { + self.poller.poll(timeout) + } + + pub fn register(&mut self, fd: RawFd, event: &mut epoll_event) -> io::Result<()> { + self.poller.register(fd, event) + } + + pub fn reregister(&mut self, fd: RawFd, event: &mut epoll_event) -> io::Result<()> { + self.poller.reregister(fd, event) + } + + pub fn unregister(&mut self, fd: RawFd) -> io::Result<()> { + self.poller.unregister(fd) + } +} + +impl AsRawFd for Poll { + fn as_raw_fd(&self) -> RawFd { + self.poller.as_raw_fd() + } +} diff --git a/src/event/src/sys/mod.rs b/src/event/src/sys/mod.rs deleted file mode 100644 index 393d11a9..00000000 --- a/src/event/src/sys/mod.rs +++ /dev/null @@ -1,43 +0,0 @@ -mod epoll; - -use std::{io, os::unix::io::RawFd, time}; -use epoll::Epoll as Epoll; -use libc::epoll_event; - -#[derive(Debug)] -pub struct Poll { - poller: Epoll, -} - -impl Poll { - pub(crate) fn new() -> io::Result { - Ok( Poll { poller: Epoll::new()?, }) - } - - pub(crate) fn poll( - &mut self, - timeout: Option, - ) -> io::Result> { - self.poller.poll(timeout) - } - - pub(crate) unsafe fn register( - &mut self, - fd: RawFd, - event: &mut epoll_event, - ) -> io::Result<()> { - self.poller.register(fd, event) - } - - pub(crate) unsafe fn reregister( - &mut self, - fd: RawFd, - event: &mut epoll_event, - ) -> io::Result<()> { - self.poller.reregister(fd, event) - } - - pub(crate) fn unregister(&mut self, fd: RawFd) -> io::Result<()> { - self.poller.unregister(fd) - } -} -- Gitee