diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-07-24 05:05:34 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-24 05:05:34 +0200 |
| commit | ee77dda77855890f41f7457ba03bf307ee1f0feb (patch) | |
| tree | 0adf60f75d571f94f08b91bd4bbf92a85d88fda1 /library/std/src/sys/pal/windows/pipe.rs | |
| parent | e56e8867968f8565e3cf6242610f1344ce16be23 (diff) | |
| parent | 8c3ce60e309d9592a50729a0dbc4a77f2b3c73c6 (diff) | |
| download | rust-ee77dda77855890f41f7457ba03bf307ee1f0feb.tar.gz rust-ee77dda77855890f41f7457ba03bf307ee1f0feb.zip | |
Rollup merge of #128092 - ChrisDenton:wrappers, r=workingjubilee
Remove wrapper functions from c.rs I'd like for the windows `c.rs` just to contain the basic platform definitions and not anything higher level unless absolutely necessary. So this removes some wrapper functions that weren't really necessary in any case. The functions are only used in a few places which themselves are relatively thin wrappers. The "interesting" bit is that we had an `AlertableIoFn` that abstracted over `ReadFileEx` and `WriteFileEx`. I've replaced this with a closure. Also I removed an `#[allow(unsafe_op_in_unsafe_fn)]` while I was moving things around.
Diffstat (limited to 'library/std/src/sys/pal/windows/pipe.rs')
| -rw-r--r-- | library/std/src/sys/pal/windows/pipe.rs | 45 |
1 files changed, 23 insertions, 22 deletions
diff --git a/library/std/src/sys/pal/windows/pipe.rs b/library/std/src/sys/pal/windows/pipe.rs index d5e2356116f..01433d68b69 100644 --- a/library/std/src/sys/pal/windows/pipe.rs +++ b/library/std/src/sys/pal/windows/pipe.rs @@ -238,15 +238,6 @@ fn random_number() -> usize { } } -// Abstracts over `ReadFileEx` and `WriteFileEx` -type AlertableIoFn = unsafe extern "system" fn( - BorrowedHandle<'_>, - *mut core::ffi::c_void, - u32, - *mut c::OVERLAPPED, - c::LPOVERLAPPED_COMPLETION_ROUTINE, -) -> c::BOOL; - impl AnonPipe { pub fn handle(&self) -> &Handle { &self.inner @@ -262,7 +253,10 @@ impl AnonPipe { pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { let result = unsafe { let len = crate::cmp::min(buf.len(), u32::MAX as usize) as u32; - self.alertable_io_internal(c::ReadFileEx, buf.as_mut_ptr() as _, len) + let ptr = buf.as_mut_ptr(); + self.alertable_io_internal(|overlapped, callback| { + c::ReadFileEx(self.inner.as_raw_handle(), ptr, len, overlapped, callback) + }) }; match result { @@ -278,7 +272,10 @@ impl AnonPipe { pub fn read_buf(&self, mut buf: BorrowedCursor<'_>) -> io::Result<()> { let result = unsafe { let len = crate::cmp::min(buf.capacity(), u32::MAX as usize) as u32; - self.alertable_io_internal(c::ReadFileEx, buf.as_mut().as_mut_ptr() as _, len) + let ptr = buf.as_mut().as_mut_ptr().cast::<u8>(); + self.alertable_io_internal(|overlapped, callback| { + c::ReadFileEx(self.inner.as_raw_handle(), ptr, len, overlapped, callback) + }) }; match result { @@ -313,7 +310,9 @@ impl AnonPipe { pub fn write(&self, buf: &[u8]) -> io::Result<usize> { unsafe { let len = crate::cmp::min(buf.len(), u32::MAX as usize) as u32; - self.alertable_io_internal(c::WriteFileEx, buf.as_ptr() as _, len) + self.alertable_io_internal(|overlapped, callback| { + c::WriteFileEx(self.inner.as_raw_handle(), buf.as_ptr(), len, overlapped, callback) + }) } } @@ -341,12 +340,9 @@ impl AnonPipe { /// [`ReadFileEx`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfileex /// [`WriteFileEx`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefileex /// [Asynchronous Procedure Call]: https://docs.microsoft.com/en-us/windows/win32/sync/asynchronous-procedure-calls - #[allow(unsafe_op_in_unsafe_fn)] unsafe fn alertable_io_internal( &self, - io: AlertableIoFn, - buf: *mut core::ffi::c_void, - len: u32, + io: impl FnOnce(&mut c::OVERLAPPED, c::LPOVERLAPPED_COMPLETION_ROUTINE) -> c::BOOL, ) -> io::Result<usize> { // Use "alertable I/O" to synchronize the pipe I/O. // This has four steps. @@ -384,20 +380,25 @@ impl AnonPipe { lpOverlapped: *mut c::OVERLAPPED, ) { // Set `async_result` using a pointer smuggled through `hEvent`. - let result = - AsyncResult { error: dwErrorCode, transferred: dwNumberOfBytesTransferred }; - *(*lpOverlapped).hEvent.cast::<Option<AsyncResult>>() = Some(result); + // SAFETY: + // At this point, the OVERLAPPED struct will have been written to by the OS, + // except for our `hEvent` field which we set to a valid AsyncResult pointer (see below) + unsafe { + let result = + AsyncResult { error: dwErrorCode, transferred: dwNumberOfBytesTransferred }; + *(*lpOverlapped).hEvent.cast::<Option<AsyncResult>>() = Some(result); + } } // STEP 1: Start the I/O operation. - let mut overlapped: c::OVERLAPPED = crate::mem::zeroed(); + let mut overlapped: c::OVERLAPPED = unsafe { crate::mem::zeroed() }; // `hEvent` is unused by `ReadFileEx` and `WriteFileEx`. // Therefore the documentation suggests using it to smuggle a pointer to the callback. overlapped.hEvent = core::ptr::addr_of_mut!(async_result) as *mut _; // Asynchronous read of the pipe. // If successful, `callback` will be called once it completes. - let result = io(self.inner.as_handle(), buf, len, &mut overlapped, Some(callback)); + let result = io(&mut overlapped, Some(callback)); if result == c::FALSE { // We can return here because the call failed. // After this we must not return until the I/O completes. @@ -408,7 +409,7 @@ impl AnonPipe { let result = loop { // STEP 2: Enter an alertable state. // The second parameter of `SleepEx` is used to make this sleep alertable. - c::SleepEx(c::INFINITE, c::TRUE); + unsafe { c::SleepEx(c::INFINITE, c::TRUE) }; if let Some(result) = async_result { break result; } |
