@@ -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- 
233224impl  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) ]  
327325unsafe  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