From 8da70cbd8297574e3c9bced63e40e040bf8e93a0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Aug 2024 08:08:20 -0700 Subject: [PATCH] Miscellaneous documentation and clippy fixes for epoll. (#1135) --- src/backend/libc/event/syscalls.rs | 23 ++++++++++++++--------- src/backend/linux_raw/event/syscalls.rs | 13 +++++++++++++ src/event/epoll.rs | 17 +++++++++-------- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/backend/libc/event/syscalls.rs b/src/backend/libc/event/syscalls.rs index 23cb93085..8f3ac0644 100644 --- a/src/backend/libc/event/syscalls.rs +++ b/src/backend/libc/event/syscalls.rs @@ -3,7 +3,7 @@ use crate::backend::c; #[cfg(any(linux_kernel, target_os = "redox"))] use crate::backend::conv::ret_u32; -use crate::backend::conv::{ret, ret_c_int, ret_owned_fd}; +use crate::backend::conv::{borrowed_fd, ret, ret_c_int, ret_owned_fd}; #[cfg(solarish)] use crate::event::port::Event; #[cfg(any( @@ -14,11 +14,14 @@ use crate::event::port::Event; ))] use crate::event::EventfdFlags; use crate::event::PollFd; -use crate::fd::OwnedFd; +use crate::fd::{BorrowedFd, OwnedFd}; use crate::io; +#[cfg(solarish)] use crate::utils::as_mut_ptr; +#[cfg(any(linux_kernel, target_os = "redox"))] +use crate::utils::as_ptr; +use core::mem::MaybeUninit; use core::ptr::null_mut; -use {crate::backend::conv::borrowed_fd, crate::fd::BorrowedFd, core::mem::MaybeUninit}; #[cfg(all(feature = "alloc", bsd))] use {crate::event::kqueue::Event, crate::utils::as_ptr, core::ptr::null}; @@ -181,10 +184,10 @@ pub(crate) fn port_send( #[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] pub(crate) fn pause() { - let r = unsafe { libc::pause() }; + let r = unsafe { c::pause() }; let errno = libc_errno::errno().0; debug_assert_eq!(r, -1); - debug_assert_eq!(errno, libc::EINTR); + debug_assert_eq!(errno, c::EINTR); } #[inline] @@ -198,7 +201,7 @@ pub(crate) fn epoll_create(flags: super::epoll::CreateFlags) -> io::Result, source: BorrowedFd, - event: &mut crate::event::epoll::Event, + event: &crate::event::epoll::Event, ) -> io::Result<()> { // We use our own `Event` struct instead of libc's because // ours preserves pointer provenance instead of just using a `u64`, @@ -208,7 +211,8 @@ pub(crate) fn epoll_add( borrowed_fd(epoll), c::EPOLL_CTL_ADD, borrowed_fd(source), - as_mut_ptr(event).cast(), + // The event is read-only even though libc has a non-const pointer. + as_ptr(event) as *mut c::epoll_event, )) } } @@ -218,14 +222,15 @@ pub(crate) fn epoll_add( pub(crate) fn epoll_mod( epoll: BorrowedFd<'_>, source: BorrowedFd, - event: &mut crate::event::epoll::Event, + event: &crate::event::epoll::Event, ) -> io::Result<()> { unsafe { ret(c::epoll_ctl( borrowed_fd(epoll), c::EPOLL_CTL_MOD, borrowed_fd(source), - as_mut_ptr(event).cast(), + // The event is read-only even though libc has a non-const pointer. + as_ptr(event) as *mut c::epoll_event, )) } } diff --git a/src/backend/linux_raw/event/syscalls.rs b/src/backend/linux_raw/event/syscalls.rs index abae5c62e..b5ad45db3 100644 --- a/src/backend/linux_raw/event/syscalls.rs +++ b/src/backend/linux_raw/event/syscalls.rs @@ -12,6 +12,7 @@ use crate::backend::conv::{ use crate::event::{epoll, EventfdFlags, PollFd}; use crate::fd::{BorrowedFd, OwnedFd}; use crate::io; +#[cfg(feature = "alloc")] use core::mem::MaybeUninit; use linux_raw_sys::general::{EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD}; #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] @@ -51,6 +52,7 @@ pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result io::Result { + // SAFETY: `__NR_epoll_create1` doesn't access any user memory. unsafe { ret_owned_fd(syscall_readonly!(__NR_epoll_create1, flags)) } } @@ -60,6 +62,8 @@ pub(crate) fn epoll_add( fd: BorrowedFd, event: &epoll::Event, ) -> io::Result<()> { + // SAFETY: `__NR_epoll_ctl` with `EPOLL_CTL_ADD` doesn't modify any user + // memory, and it only reads from `event`. unsafe { ret(syscall_readonly!( __NR_epoll_ctl, @@ -77,6 +81,8 @@ pub(crate) fn epoll_mod( fd: BorrowedFd, event: &epoll::Event, ) -> io::Result<()> { + // SAFETY: `__NR_epoll_ctl` with `EPOLL_CTL_MOD` doesn't modify any user + // memory, and it only reads from `event`. unsafe { ret(syscall_readonly!( __NR_epoll_ctl, @@ -90,6 +96,8 @@ pub(crate) fn epoll_mod( #[inline] pub(crate) fn epoll_del(epfd: BorrowedFd<'_>, fd: BorrowedFd) -> io::Result<()> { + // SAFETY: `__NR_epoll_ctl` with `EPOLL_CTL_DEL` doesn't access any user + // memory. unsafe { ret(syscall_readonly!( __NR_epoll_ctl, @@ -101,6 +109,7 @@ pub(crate) fn epoll_del(epfd: BorrowedFd<'_>, fd: BorrowedFd) -> io::Result<()> } } +#[cfg(feature = "alloc")] #[inline] pub(crate) fn epoll_wait( epfd: BorrowedFd<'_>, @@ -108,6 +117,8 @@ pub(crate) fn epoll_wait( timeout: c::c_int, ) -> io::Result { let (buf_addr_mut, buf_len) = slice_mut(events); + // SAFETY: `__NR_epoll_wait` doesn't access any user memory outside of + // the `events` array. #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] unsafe { ret_usize(syscall!( @@ -118,6 +129,8 @@ pub(crate) fn epoll_wait( c_int(timeout) )) } + // SAFETY: `__NR_epoll_pwait` doesn't access any user memory outside of + // the `events` array, as we don't pass it a `sigmask`. #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] unsafe { ret_usize(syscall!( diff --git a/src/event/epoll.rs b/src/event/epoll.rs index 07cb9da93..0990407b9 100644 --- a/src/event/epoll.rs +++ b/src/event/epoll.rs @@ -73,6 +73,7 @@ #![allow(unused_qualifications)] use super::epoll; +#[cfg(feature = "alloc")] use crate::backend::c; pub use crate::backend::event::epoll::*; use crate::backend::event::syscalls; @@ -102,14 +103,14 @@ pub fn create(flags: epoll::CreateFlags) -> io::Result { /// `epoll_ctl(self, EPOLL_CTL_ADD, data, event)`—Adds an element to an epoll /// object. /// -/// This registers interest in any of the events set in `event_flags` occurring on -/// the file descriptor associated with `data`. +/// This registers interest in any of the events set in `event_flags` occurring +/// on the file descriptor associated with `data`. /// /// Note that `close`ing a file descriptor does not necessarily unregister -/// interest which can lead to spurious events being returned from [`epoll::wait`]. If -/// a file descriptor is an `Arc`, then `epoll` can be -/// thought to maintain a `Weak` to the file descriptor. -/// Check the [faq] for details. +/// interest which can lead to spurious events being returned from +/// [`epoll::wait`]. If a file descriptor is an `Arc`, then +/// `epoll` can be thought to maintain a `Weak` to the file +/// descriptor. Check the [faq] for details. /// /// # References /// - [Linux] @@ -127,7 +128,7 @@ pub fn add( syscalls::epoll_add( epoll.as_fd(), source.as_fd(), - &mut Event { + &Event { flags: event_flags, data, #[cfg(all(libc, target_os = "redox"))] @@ -156,7 +157,7 @@ pub fn modify( syscalls::epoll_mod( epoll.as_fd(), source.as_fd(), - &mut Event { + &Event { flags: event_flags, data, #[cfg(all(libc, target_os = "redox"))]