use std::os::fd::{AsRawFd, FromRawFd, OwnedFd};
use std::{io, result};
use utils::eventfd::EventFd;
pub struct ExitHandle {
write_fd: OwnedFd,
}
impl ExitHandle {
pub(crate) fn from_event_fd(evt: &EventFd) -> result::Result<Self, io::Error> {
#[cfg(target_os = "linux")]
let raw_fd = evt.as_raw_fd();
#[cfg(target_os = "macos")]
let raw_fd = evt.get_write_fd();
let fd = unsafe { libc::dup(raw_fd) };
if fd < 0 {
return Err(io::Error::last_os_error());
}
let write_fd = unsafe { OwnedFd::from_raw_fd(fd) };
Ok(Self { write_fd })
}
pub fn trigger(&self) {
let val: u64 = 1;
let _ = unsafe {
libc::write(
self.write_fd.as_raw_fd(),
&val as *const u64 as *const libc::c_void,
std::mem::size_of::<u64>(),
)
};
}
}
impl Clone for ExitHandle {
fn clone(&self) -> Self {
let fd = unsafe { libc::dup(self.write_fd.as_raw_fd()) };
assert!(fd >= 0, "Failed to dup ExitHandle fd");
let write_fd = unsafe { OwnedFd::from_raw_fd(fd) };
Self { write_fd }
}
}
unsafe impl Send for ExitHandle {}
unsafe impl Sync for ExitHandle {}