use std::os::fd::AsRawFd as _;
use derive_new::new;
use ioctls::ioctl;
use crate::{
EventSources,
Fd,
NtSync,
errno_match,
raw,
};
use log::*;
#[repr(C)]
#[derive(Debug, new, Default)]
pub struct EventStatus {
signaled: u32,
manual: u32,
}
impl EventStatus {
pub fn manual_signal(&self) -> bool {
self.manual == 1
}
pub fn auto_signal(&self) -> bool {
self.signaled == 1
}
}
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct Event {
pub(crate) id: Fd,
}
impl Event {
pub fn signal(&self) -> crate::Result<bool> {
let mut state: u32 = 0;
if unsafe { ntsync_event_set(self.id, raw!(mut state: u32)) } == -1 {
errno_match!();
}
Ok(state != 0)
}
pub fn reset(&self) -> crate::Result<bool> {
let mut state: u32 = 0;
if unsafe { ntsync_event_reset(self.id, raw!(mut state: u32)) } == -1 {
errno_match!();
}
Ok(state != 0)
}
pub fn pulse(&self) -> crate::Result<bool> {
let mut state: u32 = 0;
if unsafe { ntsync_event_pulse(self.id, raw!(mut state: u32)) } == -1 {
errno_match!();
}
Ok(state != 0)
}
pub fn status(&self) -> crate::Result<EventStatus> {
let mut args = EventStatus::default();
if unsafe { ntsync_event_read(self.id, raw!(mut args: EventStatus)) } == -1 {
errno_match!()
}
trace!("returned args: {args:?}");
Ok(args)
}
}
unsafe impl Send for Event {}
impl From<Event> for EventSources {
fn from(val: Event) -> Self {
EventSources::Event(val)
}
}
impl NtSync {
pub fn new_event(&self) -> crate::Result<Event> {
let args = EventStatus::new(0, 0);
let result = unsafe { ntsync_create_event(self.inner.handle.as_raw_fd(), raw!(const args: EventStatus)) };
if result < 0 {
trace!("Failed to create event");
errno_match!();
}
trace!("{args:?}");
Ok(Event {
id: result as Fd,
})
}
}
ioctl!(write ntsync_create_event with b'N', 0x87; EventStatus);
ioctl!(read ntsync_event_set with b'N', 0x88; u32);
ioctl!(read ntsync_event_reset with b'N', 0x89; u32);
ioctl!(read ntsync_event_pulse with b'N', 0x8a; u32);
ioctl!(read ntsync_event_read with b'N', 0x8d; EventStatus);