polling icon indicating copy to clipboard operation
polling copied to clipboard

Add support for using CompletionPacket for overlapped I/O

Open notgull opened this issue 2 years ago • 4 comments

Closes #97

This allows the packet to be used for overlapped operations, like reading from or writing to files.

notgull avatar Aug 16 '23 18:08 notgull

Hi @notgull! What is the state of this pr? I'm willing to help with this

39555 avatar Oct 21 '24 22:10 39555

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.

notgull avatar Oct 24 '24 02:10 notgull

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 OVERLAPPED block 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.

39555 avatar Oct 24 '24 19:10 39555

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

klu-dev avatar Aug 17 '25 14:08 klu-dev