Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit de086ea

Browse files
authoredJul 24, 2024
Rollup merge of rust-lang#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.
2 parents ccba33c + 642c69b commit de086ea

File tree

3 files changed

+43
-126
lines changed

3 files changed

+43
-126
lines changed
 

‎std/src/sys/pal/windows/c.rs

+12-96
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use crate::ffi::CStr;
1010
use crate::mem;
1111
use crate::os::raw::{c_uint, c_ulong, c_ushort, c_void};
12-
use crate::os::windows::io::{AsRawHandle, BorrowedHandle};
1312
use crate::ptr;
1413

1514
pub(super) mod windows_targets;
@@ -114,89 +113,6 @@ if #[cfg(not(target_vendor = "uwp"))] {
114113
}
115114
}
116115

117-
pub unsafe extern "system" fn WriteFileEx(
118-
hFile: BorrowedHandle<'_>,
119-
lpBuffer: *mut ::core::ffi::c_void,
120-
nNumberOfBytesToWrite: u32,
121-
lpOverlapped: *mut OVERLAPPED,
122-
lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE,
123-
) -> BOOL {
124-
windows_sys::WriteFileEx(
125-
hFile.as_raw_handle(),
126-
lpBuffer.cast::<u8>(),
127-
nNumberOfBytesToWrite,
128-
lpOverlapped,
129-
lpCompletionRoutine,
130-
)
131-
}
132-
133-
pub unsafe extern "system" fn ReadFileEx(
134-
hFile: BorrowedHandle<'_>,
135-
lpBuffer: *mut ::core::ffi::c_void,
136-
nNumberOfBytesToRead: u32,
137-
lpOverlapped: *mut OVERLAPPED,
138-
lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE,
139-
) -> BOOL {
140-
windows_sys::ReadFileEx(
141-
hFile.as_raw_handle(),
142-
lpBuffer.cast::<u8>(),
143-
nNumberOfBytesToRead,
144-
lpOverlapped,
145-
lpCompletionRoutine,
146-
)
147-
}
148-
149-
cfg_if::cfg_if! {
150-
if #[cfg(not(target_vendor = "uwp"))] {
151-
pub unsafe fn NtReadFile(
152-
filehandle: BorrowedHandle<'_>,
153-
event: HANDLE,
154-
apcroutine: PIO_APC_ROUTINE,
155-
apccontext: *mut c_void,
156-
iostatusblock: &mut IO_STATUS_BLOCK,
157-
buffer: *mut crate::mem::MaybeUninit<u8>,
158-
length: u32,
159-
byteoffset: Option<&i64>,
160-
key: Option<&u32>,
161-
) -> NTSTATUS {
162-
windows_sys::NtReadFile(
163-
filehandle.as_raw_handle(),
164-
event,
165-
apcroutine,
166-
apccontext,
167-
iostatusblock,
168-
buffer.cast::<c_void>(),
169-
length,
170-
byteoffset.map(|o| o as *const i64).unwrap_or(ptr::null()),
171-
key.map(|k| k as *const u32).unwrap_or(ptr::null()),
172-
)
173-
}
174-
pub unsafe fn NtWriteFile(
175-
filehandle: BorrowedHandle<'_>,
176-
event: HANDLE,
177-
apcroutine: PIO_APC_ROUTINE,
178-
apccontext: *mut c_void,
179-
iostatusblock: &mut IO_STATUS_BLOCK,
180-
buffer: *const u8,
181-
length: u32,
182-
byteoffset: Option<&i64>,
183-
key: Option<&u32>,
184-
) -> NTSTATUS {
185-
windows_sys::NtWriteFile(
186-
filehandle.as_raw_handle(),
187-
event,
188-
apcroutine,
189-
apccontext,
190-
iostatusblock,
191-
buffer.cast::<c_void>(),
192-
length,
193-
byteoffset.map(|o| o as *const i64).unwrap_or(ptr::null()),
194-
key.map(|k| k as *const u32).unwrap_or(ptr::null()),
195-
)
196-
}
197-
}
198-
}
199-
200116
// Use raw-dylib to import ProcessPrng as we can't rely on there being an import library.
201117
cfg_if::cfg_if! {
202118
if #[cfg(not(target_vendor = "win7"))] {
@@ -331,29 +247,29 @@ compat_fn_with_fallback! {
331247
}
332248
#[cfg(target_vendor = "uwp")]
333249
pub fn NtReadFile(
334-
filehandle: BorrowedHandle<'_>,
250+
filehandle: HANDLE,
335251
event: HANDLE,
336252
apcroutine: PIO_APC_ROUTINE,
337-
apccontext: *mut c_void,
338-
iostatusblock: &mut IO_STATUS_BLOCK,
339-
buffer: *mut crate::mem::MaybeUninit<u8>,
253+
apccontext: *const core::ffi::c_void,
254+
iostatusblock: *mut IO_STATUS_BLOCK,
255+
buffer: *mut core::ffi::c_void,
340256
length: u32,
341-
byteoffset: Option<&i64>,
342-
key: Option<&u32>
257+
byteoffset: *const i64,
258+
key: *const u32
343259
) -> NTSTATUS {
344260
STATUS_NOT_IMPLEMENTED
345261
}
346262
#[cfg(target_vendor = "uwp")]
347263
pub fn NtWriteFile(
348-
filehandle: BorrowedHandle<'_>,
264+
filehandle: HANDLE,
349265
event: HANDLE,
350266
apcroutine: PIO_APC_ROUTINE,
351-
apccontext: *mut c_void,
352-
iostatusblock: &mut IO_STATUS_BLOCK,
353-
buffer: *const u8,
267+
apccontext: *const core::ffi::c_void,
268+
iostatusblock: *mut IO_STATUS_BLOCK,
269+
buffer: *const core::ffi::c_void,
354270
length: u32,
355-
byteoffset: Option<&i64>,
356-
key: Option<&u32>
271+
byteoffset: *const i64,
272+
key: *const u32
357273
) -> NTSTATUS {
358274
STATUS_NOT_IMPLEMENTED
359275
}

‎std/src/sys/pal/windows/handle.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -250,15 +250,15 @@ impl Handle {
250250
// the provided `len`.
251251
let status = unsafe {
252252
c::NtReadFile(
253-
self.as_handle(),
253+
self.as_raw_handle(),
254254
ptr::null_mut(),
255255
None,
256256
ptr::null_mut(),
257257
&mut io_status,
258-
buf,
258+
buf.cast::<core::ffi::c_void>(),
259259
len,
260-
offset.map(|n| n as _).as_ref(),
261-
None,
260+
offset.as_ref().map(|n| ptr::from_ref(n).cast::<i64>()).unwrap_or(ptr::null()),
261+
ptr::null(),
262262
)
263263
};
264264

@@ -300,15 +300,15 @@ impl Handle {
300300
let len = cmp::min(buf.len(), u32::MAX as usize) as u32;
301301
let status = unsafe {
302302
c::NtWriteFile(
303-
self.as_handle(),
303+
self.as_raw_handle(),
304304
ptr::null_mut(),
305305
None,
306306
ptr::null_mut(),
307307
&mut io_status,
308-
buf.as_ptr(),
308+
buf.as_ptr().cast::<core::ffi::c_void>(),
309309
len,
310-
offset.map(|n| n as _).as_ref(),
311-
None,
310+
offset.as_ref().map(|n| ptr::from_ref(n).cast::<i64>()).unwrap_or(ptr::null()),
311+
ptr::null(),
312312
)
313313
};
314314
let status = if status == c::STATUS_PENDING {

‎std/src/sys/pal/windows/pipe.rs

+23-22
Original file line numberDiff line numberDiff line change
@@ -238,15 +238,6 @@ fn random_number() -> usize {
238238
}
239239
}
240240

241-
// Abstracts over `ReadFileEx` and `WriteFileEx`
242-
type AlertableIoFn = unsafe extern "system" fn(
243-
BorrowedHandle<'_>,
244-
*mut core::ffi::c_void,
245-
u32,
246-
*mut c::OVERLAPPED,
247-
c::LPOVERLAPPED_COMPLETION_ROUTINE,
248-
) -> c::BOOL;
249-
250241
impl AnonPipe {
251242
pub fn handle(&self) -> &Handle {
252243
&self.inner
@@ -262,7 +253,10 @@ impl AnonPipe {
262253
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
263254
let result = unsafe {
264255
let len = crate::cmp::min(buf.len(), u32::MAX as usize) as u32;
265-
self.alertable_io_internal(c::ReadFileEx, buf.as_mut_ptr() as _, len)
256+
let ptr = buf.as_mut_ptr();
257+
self.alertable_io_internal(|overlapped, callback| {
258+
c::ReadFileEx(self.inner.as_raw_handle(), ptr, len, overlapped, callback)
259+
})
266260
};
267261

268262
match result {
@@ -278,7 +272,10 @@ impl AnonPipe {
278272
pub fn read_buf(&self, mut buf: BorrowedCursor<'_>) -> io::Result<()> {
279273
let result = unsafe {
280274
let len = crate::cmp::min(buf.capacity(), u32::MAX as usize) as u32;
281-
self.alertable_io_internal(c::ReadFileEx, buf.as_mut().as_mut_ptr() as _, len)
275+
let ptr = buf.as_mut().as_mut_ptr().cast::<u8>();
276+
self.alertable_io_internal(|overlapped, callback| {
277+
c::ReadFileEx(self.inner.as_raw_handle(), ptr, len, overlapped, callback)
278+
})
282279
};
283280

284281
match result {
@@ -313,7 +310,9 @@ impl AnonPipe {
313310
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
314311
unsafe {
315312
let len = crate::cmp::min(buf.len(), u32::MAX as usize) as u32;
316-
self.alertable_io_internal(c::WriteFileEx, buf.as_ptr() as _, len)
313+
self.alertable_io_internal(|overlapped, callback| {
314+
c::WriteFileEx(self.inner.as_raw_handle(), buf.as_ptr(), len, overlapped, callback)
315+
})
317316
}
318317
}
319318

@@ -341,12 +340,9 @@ impl AnonPipe {
341340
/// [`ReadFileEx`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfileex
342341
/// [`WriteFileEx`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefileex
343342
/// [Asynchronous Procedure Call]: https://docs.microsoft.com/en-us/windows/win32/sync/asynchronous-procedure-calls
344-
#[allow(unsafe_op_in_unsafe_fn)]
345343
unsafe fn alertable_io_internal(
346344
&self,
347-
io: AlertableIoFn,
348-
buf: *mut core::ffi::c_void,
349-
len: u32,
345+
io: impl FnOnce(&mut c::OVERLAPPED, c::LPOVERLAPPED_COMPLETION_ROUTINE) -> c::BOOL,
350346
) -> io::Result<usize> {
351347
// Use "alertable I/O" to synchronize the pipe I/O.
352348
// This has four steps.
@@ -384,20 +380,25 @@ impl AnonPipe {
384380
lpOverlapped: *mut c::OVERLAPPED,
385381
) {
386382
// Set `async_result` using a pointer smuggled through `hEvent`.
387-
let result =
388-
AsyncResult { error: dwErrorCode, transferred: dwNumberOfBytesTransferred };
389-
*(*lpOverlapped).hEvent.cast::<Option<AsyncResult>>() = Some(result);
383+
// SAFETY:
384+
// At this point, the OVERLAPPED struct will have been written to by the OS,
385+
// except for our `hEvent` field which we set to a valid AsyncResult pointer (see below)
386+
unsafe {
387+
let result =
388+
AsyncResult { error: dwErrorCode, transferred: dwNumberOfBytesTransferred };
389+
*(*lpOverlapped).hEvent.cast::<Option<AsyncResult>>() = Some(result);
390+
}
390391
}
391392

392393
// STEP 1: Start the I/O operation.
393-
let mut overlapped: c::OVERLAPPED = crate::mem::zeroed();
394+
let mut overlapped: c::OVERLAPPED = unsafe { crate::mem::zeroed() };
394395
// `hEvent` is unused by `ReadFileEx` and `WriteFileEx`.
395396
// Therefore the documentation suggests using it to smuggle a pointer to the callback.
396397
overlapped.hEvent = core::ptr::addr_of_mut!(async_result) as *mut _;
397398

398399
// Asynchronous read of the pipe.
399400
// If successful, `callback` will be called once it completes.
400-
let result = io(self.inner.as_handle(), buf, len, &mut overlapped, Some(callback));
401+
let result = io(&mut overlapped, Some(callback));
401402
if result == c::FALSE {
402403
// We can return here because the call failed.
403404
// After this we must not return until the I/O completes.
@@ -408,7 +409,7 @@ impl AnonPipe {
408409
let result = loop {
409410
// STEP 2: Enter an alertable state.
410411
// The second parameter of `SleepEx` is used to make this sleep alertable.
411-
c::SleepEx(c::INFINITE, c::TRUE);
412+
unsafe { c::SleepEx(c::INFINITE, c::TRUE) };
412413
if let Some(result) = async_result {
413414
break result;
414415
}

0 commit comments

Comments
 (0)
Failed to load comments.