use crate::{net, Result};
use core::mem;
use core::slice;
pub(crate) struct Waker {
pub fd: net::Fd,
}
impl Waker {
pub fn new() -> Result<Self> {
let fd = net::Fd::udp_socket(libc::AF_INET)?;
let addr = net::SocketAddr::inet_from("127.0.0.1:0")?;
fd.bind(&addr)?;
Ok(Self { fd })
}
pub fn wake(&self) {
let addr = self.fd.getsockname().unwrap();
let msg = &self.fd as *const _ as *const u8;
let msglen = mem::size_of_val(&self.fd);
let buf = unsafe { slice::from_raw_parts(msg, msglen) };
let _ = self.fd.try_sendto(buf, 0, &addr);
}
pub fn awaken(&self) -> bool {
let mut fd = [-1_i32; 2];
let buf = unsafe { slice::from_raw_parts_mut(fd.as_mut_ptr().cast::<u8>(), 4) };
let size = self.fd.try_read(buf).unwrap_or(0);
size == mem::size_of::<i32>() && fd[0] == self.fd.fd()
}
}