use std::os::fd::AsRawFd;
use tokio::io::unix::AsyncFd;
pub struct EventTokio(AsyncFd<base::SafeDescriptor>);
impl EventTokio {
pub fn new(event: base::Event) -> anyhow::Result<Self> {
let fd: base::SafeDescriptor = event.into();
base::add_fd_flags(fd.as_raw_fd(), libc::O_NONBLOCK)?;
Ok(Self(AsyncFd::new(fd)?))
}
pub async fn wait(&self) -> std::io::Result<()> {
loop {
let mut guard = self.0.readable().await?;
let io_result = guard.try_io(|inner| {
let mut buf: u64 = 0;
let ret = unsafe {
libc::read(
inner.as_raw_fd(),
&mut buf as *mut u64 as *mut libc::c_void,
std::mem::size_of::<u64>(),
)
};
if ret < 0 {
return Err(std::io::Error::last_os_error());
}
if ret as usize != std::mem::size_of::<u64>() {
return Err(std::io::Error::from(std::io::ErrorKind::UnexpectedEof));
}
Ok(())
});
match io_result {
Ok(result) => return result,
Err(_would_block) => continue,
}
}
}
}