@@ -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-
250241impl 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