Add support for using CompletionPacket for overlapped I/O
Closes #97
This allows the packet to be used for overlapped operations, like reading from or writing to files.
Hi @notgull! What is the state of this pr? I'm willing to help with this
There was a segfault I kept encountering that I couldn't figure out how to work around. So if that was fixed this would be good to merge.
I have an error and a crash in test_win32_io
Write error
thread 'win32_file_io' panicked at tests\windows_overlapped.rs:75:17:
WriteFile failed: The handle is invalid. (os error 6)
it seems you are using Packet struct as an OVERLAPPED object
This pointer can be used as an
OVERLAPPEDblock in Windows APIs
But the Packet actually doesn't have OVERLAPPED as the first field and isn't #[repr(C)]? Something like:
#[repr(C)]
struct Packet {
overlapped: OVERLAPPED
...
}
After changing this to
#[repr(C)]
struct Overlapped {
overlapped: OVERLAPPED,
packet: CompletionPacket
}
let packet = Overlapped {overlapped: unsafe{ std::mem::zeroed() }, ... }
it started writing.
Crash Access violation reading location
After it started writing I got the following crash
* thread #5, name = 'win32_file_io', stop reason = Exception 0xc0000005 encountered at address 0x7ff7b1c2ddc7: Access violation reading location 0x00000010
frame #0: 0x00007ff7b1c2ddc7 windows_overlapped-11aba7b23d31a0bc.exe`union enum2$<core::result::Result<tuple$<>,std::io::error::Error> > polling::iocp::afd::Afd<core::pin::Pin<alloc::sync::Arc<polling::iocp::afd::IoStatusBlock<enum2$<polling::iocp::PacketInner> >,alloc::alloc::Global> > >::poll<core::pin::Pin<alloc::sync::Arc<polling::iocp::afd::IoStatusBlock<enum2$<polling::iocp::PacketInner> >,alloc::alloc::Global> > >(self=0x0000000000000010, packet=Pin<alloc::sync::Arc<polling::iocp::afd::IoStatusBlock<enum2$<polling::iocp::PacketInner> >,alloc::alloc::Global> > @ 0x00000056d3bfcb50, base_socket=140701816385568, afd_events=(__0 = 1096427487)) at afd.rs:479
476 let ntdll = NtdllImports::get()?;
477 let result = unsafe {
478 ntdll.NtDeviceIoControlFile(
-> 479 self.handle,
480 ptr::null_mut(),
481 ptr::null_mut(),
482 iosb.cast(),
Crash STATUS_HEAP_CORRUPTION
I've decided to add overlapped directly to IoStatusBlock
#[repr(C)]
pub(crate) struct IoStatusBlock<T> {
-> overlapped: OVERLAPPED,
It started partially working, but there is some undefined behavior: after some time, I encountered a segfault with (exit code: 0xc0000374, STATUS_HEAP_CORRUPTION) or ASSESS_VIOLATION when WriteFile, ReadFile works though.
Hi @notgull! I implement another version which use mio named pipe idea to use completion key to differentiate file overlapped pointer and normal Packet block pointer. The file overlapped pointer has offset to the Packet block and can be converted to Packet. The add_file api return read/write overlapped pointer for caller used as overlapped pointer parameter in windows WriteFile/ReadFile API. PR https://github.com/smol-rs/polling/pull/248