Skip to content

Commit 74716a3

Browse files
authored
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 67f98e3 + 8c3ce60 commit 74716a3

File tree

3 files changed

+43
-126
lines changed

3 files changed

+43
-126
lines changed

library/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
}

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

+8-8
Original file line numberDiff line numberDiff line change
@@ -243,15 +243,15 @@ impl Handle {
243243
// the provided `len`.
244244
let status = unsafe {
245245
c::NtReadFile(
246-
self.as_handle(),
246+
self.as_raw_handle(),
247247
ptr::null_mut(),
248248
None,
249249
ptr::null_mut(),
250250
&mut io_status,
251-
buf,
251+
buf.cast::<core::ffi::c_void>(),
252252
len,
253-
offset.map(|n| n as _).as_ref(),
254-
None,
253+
offset.as_ref().map(|n| ptr::from_ref(n).cast::<i64>()).unwrap_or(ptr::null()),
254+
ptr::null(),
255255
)
256256
};
257257

@@ -293,15 +293,15 @@ impl Handle {
293293
let len = cmp::min(buf.len(), u32::MAX as usize) as u32;
294294
let status = unsafe {
295295
c::NtWriteFile(
296-
self.as_handle(),
296+
self.as_raw_handle(),
297297
ptr::null_mut(),
298298
None,
299299
ptr::null_mut(),
300300
&mut io_status,
301-
buf.as_ptr(),
301+
buf.as_ptr().cast::<core::ffi::c_void>(),
302302
len,
303-
offset.map(|n| n as _).as_ref(),
304-
None,
303+
offset.as_ref().map(|n| ptr::from_ref(n).cast::<i64>()).unwrap_or(ptr::null()),
304+
ptr::null(),
305305
)
306306
};
307307
let status = if status == c::STATUS_PENDING {

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

+23-22
Original file line numberDiff line numberDiff line change
@@ -221,15 +221,6 @@ fn random_number() -> usize {
221221
}
222222
}
223223

224-
// Abstracts over `ReadFileEx` and `WriteFileEx`
225-
type AlertableIoFn = unsafe extern "system" fn(
226-
BorrowedHandle<'_>,
227-
*mut core::ffi::c_void,
228-
u32,
229-
*mut c::OVERLAPPED,
230-
c::LPOVERLAPPED_COMPLETION_ROUTINE,
231-
) -> c::BOOL;
232-
233224
impl AnonPipe {
234225
pub fn handle(&self) -> &Handle {
235226
&self.inner
@@ -244,7 +235,10 @@ impl AnonPipe {
244235
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
245236
let result = unsafe {
246237
let len = crate::cmp::min(buf.len(), u32::MAX as usize) as u32;
247-
self.alertable_io_internal(c::ReadFileEx, buf.as_mut_ptr() as _, len)
238+
let ptr = buf.as_mut_ptr();
239+
self.alertable_io_internal(|overlapped, callback| {
240+
c::ReadFileEx(self.inner.as_raw_handle(), ptr, len, overlapped, callback)
241+
})
248242
};
249243

250244
match result {
@@ -260,7 +254,10 @@ impl AnonPipe {
260254
pub fn read_buf(&self, mut buf: BorrowedCursor<'_>) -> io::Result<()> {
261255
let result = unsafe {
262256
let len = crate::cmp::min(buf.capacity(), u32::MAX as usize) as u32;
263-
self.alertable_io_internal(c::ReadFileEx, buf.as_mut().as_mut_ptr() as _, len)
257+
let ptr = buf.as_mut().as_mut_ptr().cast::<u8>();
258+
self.alertable_io_internal(|overlapped, callback| {
259+
c::ReadFileEx(self.inner.as_raw_handle(), ptr, len, overlapped, callback)
260+
})
264261
};
265262

266263
match result {
@@ -295,7 +292,9 @@ impl AnonPipe {
295292
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
296293
unsafe {
297294
let len = crate::cmp::min(buf.len(), u32::MAX as usize) as u32;
298-
self.alertable_io_internal(c::WriteFileEx, buf.as_ptr() as _, len)
295+
self.alertable_io_internal(|overlapped, callback| {
296+
c::WriteFileEx(self.inner.as_raw_handle(), buf.as_ptr(), len, overlapped, callback)
297+
})
299298
}
300299
}
301300

@@ -323,12 +322,9 @@ impl AnonPipe {
323322
/// [`ReadFileEx`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfileex
324323
/// [`WriteFileEx`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefileex
325324
/// [Asynchronous Procedure Call]: https://docs.microsoft.com/en-us/windows/win32/sync/asynchronous-procedure-calls
326-
#[allow(unsafe_op_in_unsafe_fn)]
327325
unsafe fn alertable_io_internal(
328326
&self,
329-
io: AlertableIoFn,
330-
buf: *mut core::ffi::c_void,
331-
len: u32,
327+
io: impl FnOnce(&mut c::OVERLAPPED, c::LPOVERLAPPED_COMPLETION_ROUTINE) -> c::BOOL,
332328
) -> io::Result<usize> {
333329
// Use "alertable I/O" to synchronize the pipe I/O.
334330
// This has four steps.
@@ -366,20 +362,25 @@ impl AnonPipe {
366362
lpOverlapped: *mut c::OVERLAPPED,
367363
) {
368364
// Set `async_result` using a pointer smuggled through `hEvent`.
369-
let result =
370-
AsyncResult { error: dwErrorCode, transferred: dwNumberOfBytesTransferred };
371-
*(*lpOverlapped).hEvent.cast::<Option<AsyncResult>>() = Some(result);
365+
// SAFETY:
366+
// At this point, the OVERLAPPED struct will have been written to by the OS,
367+
// except for our `hEvent` field which we set to a valid AsyncResult pointer (see below)
368+
unsafe {
369+
let result =
370+
AsyncResult { error: dwErrorCode, transferred: dwNumberOfBytesTransferred };
371+
*(*lpOverlapped).hEvent.cast::<Option<AsyncResult>>() = Some(result);
372+
}
372373
}
373374

374375
// STEP 1: Start the I/O operation.
375-
let mut overlapped: c::OVERLAPPED = crate::mem::zeroed();
376+
let mut overlapped: c::OVERLAPPED = unsafe { crate::mem::zeroed() };
376377
// `hEvent` is unused by `ReadFileEx` and `WriteFileEx`.
377378
// Therefore the documentation suggests using it to smuggle a pointer to the callback.
378379
overlapped.hEvent = core::ptr::addr_of_mut!(async_result) as *mut _;
379380

380381
// Asynchronous read of the pipe.
381382
// If successful, `callback` will be called once it completes.
382-
let result = io(self.inner.as_handle(), buf, len, &mut overlapped, Some(callback));
383+
let result = io(&mut overlapped, Some(callback));
383384
if result == c::FALSE {
384385
// We can return here because the call failed.
385386
// After this we must not return until the I/O completes.
@@ -390,7 +391,7 @@ impl AnonPipe {
390391
let result = loop {
391392
// STEP 2: Enter an alertable state.
392393
// The second parameter of `SleepEx` is used to make this sleep alertable.
393-
c::SleepEx(c::INFINITE, c::TRUE);
394+
unsafe { c::SleepEx(c::INFINITE, c::TRUE) };
394395
if let Some(result) = async_result {
395396
break result;
396397
}

0 commit comments

Comments
 (0)