1 use crate::errno::Errno;
2 use crate::{Result,unistd};
3 use std::os::unix::io::{FromRawFd, OwnedFd, AsRawFd, AsFd, RawFd, BorrowedFd};
4 
5 libc_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")]
eventfd(initval: libc::c_uint, flags: EfdFlags) -> Result<OwnedFd>14 pub 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)]
22 pub struct EventFd(OwnedFd);
23 impl EventFd {
24     /// [`EventFd::from_value_and_flags`] with `init_val = 0` and `flags = EfdFlags::empty()`.
new() -> Result<Self>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`].
from_value_and_flags(init_val: u32, flags: EfdFlags) -> Result<Self>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`.
from_flags(flags: EfdFlags) -> Result<Self>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()`.
from_value(init_val: u32) -> Result<Self>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`.
arm(&self) -> Result<usize>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`.
defuse(&self) -> Result<usize>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`.
write(&self, value: u64) -> Result<usize>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.
read(&self) -> Result<u64>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 {
as_fd(&self) -> BorrowedFd71     fn as_fd(&self) -> BorrowedFd {
72         self.0.as_fd()
73     }
74 }
75 impl AsRawFd for EventFd {
as_raw_fd(&self) -> RawFd76     fn as_raw_fd(&self) -> RawFd {
77         self.0.as_raw_fd()
78     }
79 }
80 impl From<EventFd> for OwnedFd {
from(x: EventFd) -> OwnedFd81     fn from(x: EventFd) -> OwnedFd {
82         x.0
83     }
84 }
85