@@ -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) ]
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