use std::io;
use std::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle, OwnedHandle};
use windows_sys::Win32::Foundation::HANDLE;
use windows_sys::Win32::System::IO::{GetOverlappedResult, OVERLAPPED};
use crate::{Operation, OperationState, UnassociatedEndpoint};
#[derive(Debug)]
pub struct BlockingEndpoint {
handle: OwnedHandle,
}
impl BlockingEndpoint {
#[must_use]
pub fn new(endpoint: UnassociatedEndpoint) -> Self {
Self {
handle: endpoint.into_handle(),
}
}
#[must_use]
pub fn handle(&self) -> BorrowedHandle<'_> {
self.handle.as_handle()
}
pub unsafe fn run<P, F>(&self, operation: &mut Operation<P>, issue: F) -> io::Result<usize>
where
F: FnOnce(BorrowedHandle<'_>, *mut OVERLAPPED) -> io::Result<()>,
{
operation.set_state(OperationState::Submitted);
let overlapped = operation.overlapped_ptr();
issue(self.handle(), overlapped)?;
operation.set_state(OperationState::Pending);
let mut transferred: u32 = 0;
let ok = unsafe { GetOverlappedResult(self.raw_handle(), overlapped, &mut transferred, 1) };
if ok == 0 {
return Err(io::Error::last_os_error());
}
operation.set_state(OperationState::Completed);
Ok(transferred as usize)
}
fn raw_handle(&self) -> HANDLE {
self.handle.as_raw_handle()
}
}