Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: document sys/eventfd #2450

Merged
merged 2 commits into from
Jun 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 34 additions & 2 deletions src/sys/eventfd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ use crate::{unistd, Result};
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd};

libc_bitflags! {
/// Eventfd flags.
pub struct EfdFlags: libc::c_int {
/// Set the close-on-exec (`FD_CLOEXEC`) flag on the new event file descriptor.
EFD_CLOEXEC; // Since Linux 2.6.27/FreeBSD 13.0
/// Set the `O_NONBLOCK` file status flag on the new event file description.
EFD_NONBLOCK; // Since Linux 2.6.27/FreeBSD 13.0
/// Provide semaphore-like semantics for reads from the new event file
/// descriptor.
EFD_SEMAPHORE; // Since Linux 2.6.30/FreeBSD 13.0
}
}
Expand All @@ -14,20 +19,24 @@ libc_bitflags! {
since = "0.28.0",
note = "Use EventFd::from_value_and_flags() instead"
)]
#[allow(missing_docs)]
pub fn eventfd(initval: libc::c_uint, flags: EfdFlags) -> Result<OwnedFd> {
let res = unsafe { libc::eventfd(initval, flags.bits()) };

Errno::result(res).map(|r| unsafe { OwnedFd::from_raw_fd(r) })
}

/// An eventfd file descriptor.
#[derive(Debug)]
#[repr(transparent)]
pub struct EventFd(OwnedFd);

impl EventFd {
/// [`EventFd::from_value_and_flags`] with `init_val = 0` and `flags = EfdFlags::empty()`.
pub fn new() -> Result<Self> {
Self::from_value_and_flags(0, EfdFlags::empty())
}

/// Constructs [`EventFd`] with the given `init_val` and `flags`.
///
/// Wrapper around [`libc::eventfd`].
Expand All @@ -38,35 +47,58 @@ impl EventFd {
let res = unsafe { libc::eventfd(init_val, flags.bits()) };
Errno::result(res).map(|r| Self(unsafe { OwnedFd::from_raw_fd(r) }))
}

/// [`EventFd::from_value_and_flags`] with `init_val = 0` and given `flags`.
pub fn from_flags(flags: EfdFlags) -> Result<Self> {
Self::from_value_and_flags(0, flags)
}

/// [`EventFd::from_value_and_flags`] with given `init_val` and `flags = EfdFlags::empty()`.
pub fn from_value(init_val: u32) -> Result<Self> {
Self::from_value_and_flags(init_val, EfdFlags::empty())
}

/// Arms `self`, a following call to `poll`, `select` or `epoll` will return immediately.
///
/// [`EventFd::write`] with `1`.
pub fn arm(&self) -> Result<usize> {
self.write(1)
}

/// Defuses `self`, a following call to `poll`, `select` or `epoll` will block.
///
/// [`EventFd::write`] with `0`.
pub fn defuse(&self) -> Result<usize> {
self.write(0)
}
/// Enqueues `value` triggers.

/// Enqueues `value` triggers, i.e., adds the integer value supplied in `value`
/// to the counter.
///
/// The next `value` calls to `poll`, `select` or `epoll` will return immediately.
///
/// [`EventFd::write`] with `value`.
pub fn write(&self, value: u64) -> Result<usize> {
unistd::write(&self.0, &value.to_ne_bytes())
}
// Reads the value from the file descriptor.

/// Reads the value from the file descriptor.
///
/// * If [`EFD_SEMAPHORE`](EfdFlags::EFD_SEMAPHORE) was not specified and
/// the eventfd counter has a nonzero value, then this function returns
/// an `u64` containing that value, and the counter's value is reset to
/// zero.
///
/// * If [`EFD_SEMAPHORE`](EfdFlags::EFD_SEMAPHORE) was specified and the
/// eventfd counter has a nonzero value, then this function returns an
/// `u64` containing the value 1, and the counter's value is decremented
/// by 1.
///
/// * If the eventfd counter is zero at the time of this call, then the
/// call either blocks until the counter becomes nonzero (at which time,
/// this function proceeds as described above) or fails with the error
/// `EAGAIN` if the file descriptor has been made nonblocking with
/// [`EFD_NONBLOCK`](EfdFlags::EFD_NONBLOCK).
pub fn read(&self) -> Result<u64> {
let mut arr = [0; std::mem::size_of::<u64>()];
unistd::read(&self.0, &mut arr)?;
Expand Down
2 changes: 1 addition & 1 deletion src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ feature! {
#[cfg(bsd)]
pub mod event;

/// Event file descriptor.
#[cfg(any(linux_android, target_os = "freebsd"))]
#[allow(missing_docs)]
pub mod eventfd;
}

Expand Down