Skip to content

Commit 9113d60

Browse files
feat: EventFd type (#1945)
1 parent 1c189d9 commit 9113d60

File tree

4 files changed

+74
-5
lines changed

4 files changed

+74
-5
lines changed

changelog/1945.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added `EventFd` type.

changelog/1945.changed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Deprecated `sys::eventfd::eventfd`.

src/sys/epoll.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl EpollEvent {
7272

7373
/// A safe wrapper around [`epoll`](https://man7.org/linux/man-pages/man7/epoll.7.html).
7474
/// ```
75-
/// # use nix::sys::{epoll::{EpollTimeout, Epoll, EpollEvent, EpollFlags, EpollCreateFlags}, eventfd::{eventfd, EfdFlags}};
75+
/// # use nix::sys::{epoll::{EpollTimeout, Epoll, EpollEvent, EpollFlags, EpollCreateFlags}, eventfd::{EventFd, EfdFlags}};
7676
/// # use nix::unistd::write;
7777
/// # use std::os::unix::io::{OwnedFd, FromRawFd, AsFd};
7878
/// # use std::time::{Instant, Duration};
@@ -84,11 +84,11 @@ impl EpollEvent {
8484
/// let epoll = Epoll::new(EpollCreateFlags::empty())?;
8585
///
8686
/// // Create eventfd & Add event
87-
/// let eventfd = eventfd(0, EfdFlags::empty())?;
87+
/// let eventfd = EventFd::new()?;
8888
/// epoll.add(&eventfd, EpollEvent::new(EpollFlags::EPOLLIN,DATA))?;
8989
///
9090
/// // Arm eventfd & Time wait
91-
/// write(&eventfd, &1u64.to_ne_bytes())?;
91+
/// eventfd.arm()?;
9292
/// let now = Instant::now();
9393
///
9494
/// // Wait on event

src/sys/eventfd.rs

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::errno::Errno;
2-
use crate::Result;
3-
use std::os::unix::io::{FromRawFd, OwnedFd};
2+
use crate::{Result,unistd};
3+
use std::os::unix::io::{FromRawFd, OwnedFd, AsRawFd, AsFd, RawFd, BorrowedFd};
44

55
libc_bitflags! {
66
pub struct EfdFlags: libc::c_int {
@@ -10,8 +10,75 @@ libc_bitflags! {
1010
}
1111
}
1212

13+
#[deprecated(since = "0.28.0", note = "Use EventFd::from_value_and_flags() instead")]
1314
pub fn eventfd(initval: libc::c_uint, flags: EfdFlags) -> Result<OwnedFd> {
1415
let res = unsafe { libc::eventfd(initval, flags.bits()) };
1516

1617
Errno::result(res).map(|r| unsafe { OwnedFd::from_raw_fd(r) })
1718
}
19+
20+
#[derive(Debug)]
21+
#[repr(transparent)]
22+
pub struct EventFd(OwnedFd);
23+
impl EventFd {
24+
/// [`EventFd::from_value_and_flags`] with `init_val = 0` and `flags = EfdFlags::empty()`.
25+
pub fn new() -> Result<Self> {
26+
Self::from_value_and_flags(0, EfdFlags::empty())
27+
}
28+
/// Constructs [`EventFd`] with the given `init_val` and `flags`.
29+
///
30+
/// Wrapper around [`libc::eventfd`].
31+
pub fn from_value_and_flags(init_val: u32, flags: EfdFlags) -> Result<Self> {
32+
let res = unsafe { libc::eventfd(init_val, flags.bits()) };
33+
Errno::result(res).map(|r| Self(unsafe { OwnedFd::from_raw_fd(r) }))
34+
}
35+
/// [`EventFd::from_value_and_flags`] with `init_val = 0` and given `flags`.
36+
pub fn from_flags(flags: EfdFlags) -> Result<Self> {
37+
Self::from_value_and_flags(0, flags)
38+
}
39+
/// [`EventFd::from_value_and_flags`] with given `init_val` and `flags = EfdFlags::empty()`.
40+
pub fn from_value(init_val: u32) -> Result<Self> {
41+
Self::from_value_and_flags(init_val, EfdFlags::empty())
42+
}
43+
/// Arms `self`, a following call to `poll`, `select` or `epoll` will return immediately.
44+
///
45+
/// [`EventFd::write`] with `1`.
46+
pub fn arm(&self) -> Result<usize> {
47+
self.write(1)
48+
}
49+
/// Defuses `self`, a following call to `poll`, `select` or `epoll` will block.
50+
///
51+
/// [`EventFd::write`] with `0`.
52+
pub fn defuse(&self) -> Result<usize> {
53+
self.write(0)
54+
}
55+
/// Enqueues `value` triggers.
56+
///
57+
/// The next `value` calls to `poll`, `select` or `epoll` will return immediately.
58+
///
59+
/// [`EventFd::write`] with `value`.
60+
pub fn write(&self, value: u64) -> Result<usize> {
61+
unistd::write(&self.0,&value.to_ne_bytes())
62+
}
63+
// Reads the value from the file descriptor.
64+
pub fn read(&self) -> Result<u64> {
65+
let mut arr = [0; std::mem::size_of::<u64>()];
66+
unistd::read(self.0.as_raw_fd(),&mut arr)?;
67+
Ok(u64::from_ne_bytes(arr))
68+
}
69+
}
70+
impl AsFd for EventFd {
71+
fn as_fd(&self) -> BorrowedFd {
72+
self.0.as_fd()
73+
}
74+
}
75+
impl AsRawFd for EventFd {
76+
fn as_raw_fd(&self) -> RawFd {
77+
self.0.as_raw_fd()
78+
}
79+
}
80+
impl From<EventFd> for OwnedFd {
81+
fn from(x: EventFd) -> OwnedFd {
82+
x.0
83+
}
84+
}

0 commit comments

Comments
 (0)