nix/sys/
eventfd.rs

1use crate::errno::Errno;
2use crate::{Result,unistd};
3use std::os::unix::io::{FromRawFd, OwnedFd, AsRawFd, AsFd, RawFd, BorrowedFd};
4
5libc_bitflags! {
6    pub struct EfdFlags: libc::c_int {
7        EFD_CLOEXEC; // Since Linux 2.6.27/FreeBSD 13.0
8        EFD_NONBLOCK; // Since Linux 2.6.27/FreeBSD 13.0
9        EFD_SEMAPHORE; // Since Linux 2.6.30/FreeBSD 13.0
10    }
11}
12
13#[deprecated(since = "0.28.0", note = "Use EventFd::from_value_and_flags() instead")]
14pub fn eventfd(initval: libc::c_uint, flags: EfdFlags) -> Result<OwnedFd> {
15    let res = unsafe { libc::eventfd(initval, flags.bits()) };
16
17    Errno::result(res).map(|r| unsafe { OwnedFd::from_raw_fd(r) })
18}
19
20#[derive(Debug)]
21#[repr(transparent)]
22pub struct EventFd(OwnedFd);
23impl 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}
70impl AsFd for EventFd {
71    fn as_fd(&self) -> BorrowedFd {
72        self.0.as_fd()
73    }
74}
75impl AsRawFd for EventFd {
76    fn as_raw_fd(&self) -> RawFd {
77        self.0.as_raw_fd()
78    }
79}
80impl From<EventFd> for OwnedFd {
81    fn from(x: EventFd) -> OwnedFd {
82        x.0
83    }
84}