use std::io;
use std::os::fd::RawFd;
#[derive(Clone, Copy)]
pub(crate) struct WakeHandle {
fd: RawFd,
}
impl WakeHandle {
pub(crate) fn from_raw_fd(fd: RawFd) -> Self {
WakeHandle { fd }
}
#[allow(dead_code)]
pub(crate) fn as_raw_fd(&self) -> RawFd {
self.fd
}
pub(crate) fn wake(&self) {
#[cfg(has_io_uring)]
{
let val: u64 = 1;
unsafe {
libc::write(self.fd, &val as *const u64 as *const libc::c_void, 8);
}
}
#[cfg(not(has_io_uring))]
{
let val: u8 = 1;
unsafe {
libc::write(self.fd, &val as *const u8 as *const libc::c_void, 1);
}
}
}
}
#[cfg(has_io_uring)]
pub(crate) fn create_wake_fd() -> io::Result<(RawFd, WakeHandle)> {
let efd = unsafe { libc::eventfd(0, libc::EFD_NONBLOCK | libc::EFD_CLOEXEC) };
if efd < 0 {
return Err(io::Error::last_os_error());
}
Ok((efd, WakeHandle::from_raw_fd(efd)))
}
#[cfg(not(has_io_uring))]
pub(crate) fn create_wake_fd() -> io::Result<(RawFd, WakeHandle)> {
let mut fds = [0i32; 2];
if unsafe { libc::pipe(fds.as_mut_ptr()) } < 0 {
return Err(io::Error::last_os_error());
}
let read_fd = fds[0];
let write_fd = fds[1];
for fd in &fds {
unsafe {
let flags = libc::fcntl(*fd, libc::F_GETFL);
libc::fcntl(*fd, libc::F_SETFL, flags | libc::O_NONBLOCK);
let fd_flags = libc::fcntl(*fd, libc::F_GETFD);
libc::fcntl(*fd, libc::F_SETFD, fd_flags | libc::FD_CLOEXEC);
}
}
Ok((read_fd, WakeHandle::from_raw_fd(write_fd)))
}