use std::os::fd::AsRawFd as _;
use derive_new::new;
use ioctls::ioctl;
use log::*;
use crate::{
EventSources,
Fd,
NtSync,
OwnerId,
errno_match,
raw,
};
#[repr(C)]
#[derive(Debug, new, Default)]
pub struct MutexArgs {
owner: OwnerId,
#[new(value = "0")]
count: u32,
}
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct Mutex {
pub(crate) id: Fd,
}
unsafe impl Send for Mutex {}
impl Into<EventSources> for Mutex {
fn into(self) -> EventSources {
EventSources::Mutex(self)
}
}
impl Mutex {
pub fn unlock(&self, owner: OwnerId) -> crate::Result<()> {
let mut args = MutexArgs::new(owner);
if unsafe { ntsync_mutex_unlock(self.id, raw!(mut args: MutexArgs)) } == -1 {
errno_match!()
}
Ok(())
}
#[allow(unused)]
pub fn read(&self) -> crate::Result<MutexArgs> {
let mut args = MutexArgs::default();
if unsafe { ntsync_mutex_read(self.id, raw!(mut args: MutexArgs)) } == -1 {
errno_match!()
}
Ok(args)
}
}
impl NtSync {
pub fn new_mutex(&self) -> crate::Result<Mutex> {
let args = MutexArgs::default();
let result = unsafe { ntsync_create_mutex(self.inner.handle.as_raw_fd(), raw!( const args: MutexArgs)) };
if result < 0 {
trace!("Failed to create mutex");
errno_match!();
}
trace!("{args:?}");
Ok(Mutex {
id: result as Fd,
})
}
}
ioctl!(write ntsync_create_mutex with b'N', 0x84; MutexArgs);
ioctl!(readwrite ntsync_mutex_unlock with b'N', 0x85; MutexArgs);
ioctl!(write ntsync_mutex_kill with b'N', 0x86; u32);
ioctl!(read ntsync_mutex_read with b'N', 0x8c; MutexArgs);