Rollup merge of #128092 - ChrisDenton:wrappers, r=workingjubilee · model-checking/verify-rust-std@de086ea (original) (raw)
`@@ -238,15 +238,6 @@ fn random_number() -> usize {
`
238
238
`}
`
239
239
`}
`
240
240
``
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
``
-
250
241
`impl AnonPipe {
`
251
242
`pub fn handle(&self) -> &Handle {
`
252
243
`&self.inner
`
`@@ -262,7 +253,10 @@ impl AnonPipe {
`
262
253
`pub fn read(&self, buf: &mut [u8]) -> io::Result {
`
263
254
`let result = unsafe {
`
264
255
`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
`+
})
`
266
260
`};
`
267
261
``
268
262
`match result {
`
`@@ -278,7 +272,10 @@ impl AnonPipe {
`
278
272
`pub fn read_buf(&self, mut buf: BorrowedCursor<'_>) -> io::Result<()> {
`
279
273
`let result = unsafe {
`
280
274
`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::();
`
``
276
`+
self.alertable_io_internal(|overlapped, callback| {
`
``
277
`+
c::ReadFileEx(self.inner.as_raw_handle(), ptr, len, overlapped, callback)
`
``
278
`+
})
`
282
279
`};
`
283
280
``
284
281
`match result {
`
`@@ -313,7 +310,9 @@ impl AnonPipe {
`
313
310
`pub fn write(&self, buf: &[u8]) -> io::Result {
`
314
311
`unsafe {
`
315
312
`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
`+
})
`
317
316
`}
`
318
317
`}
`
319
318
``
`@@ -341,12 +340,9 @@ impl AnonPipe {
`
341
340
`` /// [ReadFileEx
]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfileex
``
342
341
`` /// [WriteFileEx
]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefileex
``
343
342
`/// [Asynchronous Procedure Call]: https://docs.microsoft.com/en-us/windows/win32/sync/asynchronous-procedure-calls
`
344
``
`-
#[allow(unsafe_op_in_unsafe_fn)]
`
345
343
`unsafe fn alertable_io_internal(
`
346
344
`&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,
`
350
346
`) -> io::Result {
`
351
347
`// Use "alertable I/O" to synchronize the pipe I/O.
`
352
348
`// This has four steps.
`
`@@ -384,20 +380,25 @@ impl AnonPipe {
`
384
380
`lpOverlapped: *mut c::OVERLAPPED,
`
385
381
`) {
`
386
382
`` // Set async_result
using a pointer smuggled through hEvent
.
``
387
``
`-
let result =
`
388
``
`-
AsyncResult { error: dwErrorCode, transferred: dwNumberOfBytesTransferred };
`
389
``
`-
*(*lpOverlapped).hEvent.cast::<Option>() = 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>() = Some(result);
`
``
390
`+
}
`
390
391
`}
`
391
392
``
392
393
`// 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() };
`
394
395
`` // hEvent
is unused by ReadFileEx
and WriteFileEx
.
``
395
396
`// Therefore the documentation suggests using it to smuggle a pointer to the callback.
`
396
397
` overlapped.hEvent = core::ptr::addr_of_mut!(async_result) as *mut _;
`
397
398
``
398
399
`// Asynchronous read of the pipe.
`
399
400
`` // 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));
`
401
402
`if result == c::FALSE {
`
402
403
`// We can return here because the call failed.
`
403
404
`// After this we must not return until the I/O completes.
`
`@@ -408,7 +409,7 @@ impl AnonPipe {
`
408
409
`let result = loop {
`
409
410
`// STEP 2: Enter an alertable state.
`
410
411
`` // 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) };
`
412
413
`if let Some(result) = async_result {
`
413
414
`break result;
`
414
415
`}
`