@@ -340,6 +340,9 @@ impl WinHandle {
340340/// Helper struct for all data being aliased by the kernel during async reads.
341341#[ derive( Debug ) ]
342342struct AsyncData {
343+ /// File handle of the pipe on which the async operation is performed.
344+ handle : WinHandle ,
345+
343346 /// Meta-data for this async read operation, filled by the kernel.
344347 ///
345348 /// This must be on the heap, in order for its memory location --
@@ -362,12 +365,21 @@ struct AsyncData {
362365#[ derive( Debug ) ]
363366struct MessageReader {
364367 /// The pipe read handle.
368+ ///
369+ /// Note: this is only set while no async read operation
370+ /// is currently in progress with the kernel.
371+ /// When an async read is in progress,
372+ /// it is moved into the `async` sub-structure (see below)
373+ /// along with the other fields used for the async operation,
374+ /// to make sure they all stay in sync,
375+ /// and nothing else can meddle with the the pipe
376+ /// until the operation is completed.
365377 handle : WinHandle ,
366378
367379 /// Buffer for outstanding data, that has been received but not yet processed.
368380 ///
369- /// Note: this is only set while no async read operation
370- /// is currently in progress with the kernel .
381+ /// Note: just like `handle` above,
382+ /// this is only set while no async read is in progress .
371383 /// When an async read is in progress,
372384 /// the receive buffer is aliased by the kernel;
373385 /// so we need to temporarily move it into an `AliasedCell`,
@@ -466,7 +478,7 @@ impl MessageReader {
466478 /// and the caller should not attempt waiting for completion.
467479 fn issue_async_cancel ( & mut self ) {
468480 unsafe {
469- let status = kernel32:: CancelIoEx ( self . handle . as_raw ( ) ,
481+ let status = kernel32:: CancelIoEx ( self . async . as_ref ( ) . unwrap ( ) . alias ( ) . handle . as_raw ( ) ,
470482 self . async . as_mut ( ) . unwrap ( ) . alias_mut ( ) . ov . deref_mut ( ) ) ;
471483
472484 if status == winapi:: FALSE {
@@ -486,7 +498,9 @@ impl MessageReader {
486498 // and the caller should not attempt to wait for completion.
487499 assert ! ( GetLastError ( ) == winapi:: ERROR_NOT_FOUND ) ;
488500
489- self . read_buf = self . async . take ( ) . unwrap ( ) . into_inner ( ) . buf ;
501+ let async_data = self . async . take ( ) . unwrap ( ) . into_inner ( ) ;
502+ self . handle = async_data. handle ;
503+ self . read_buf = async_data. buf ;
490504 }
491505 }
492506 }
@@ -543,14 +557,15 @@ impl MessageReader {
543557
544558 // issue the read to the buffer, at the current length offset
545559 self . async = Some ( AliasedCell :: new ( AsyncData {
560+ handle : self . handle . take ( ) ,
546561 ov : Box :: new ( mem:: zeroed ( ) ) ,
547562 buf : mem:: replace ( & mut self . read_buf , vec ! [ ] ) ,
548563 } ) ) ;
549564 let mut bytes_read: u32 = 0 ;
550565 let ok = {
551566 let async_data = self . async . as_mut ( ) . unwrap ( ) . alias_mut ( ) ;
552567 let remaining_buf = & mut async_data. buf [ buf_len..] ;
553- kernel32:: ReadFile ( self . handle . as_raw ( ) ,
568+ kernel32:: ReadFile ( async_data . handle . as_raw ( ) ,
554569 remaining_buf. as_mut_ptr ( ) as LPVOID ,
555570 remaining_buf. len ( ) as u32 ,
556571 & mut bytes_read,
@@ -593,11 +608,18 @@ impl MessageReader {
593608 } ,
594609 Err ( winapi:: ERROR_BROKEN_PIPE ) => {
595610 win32_trace ! ( "[$ {:?}] BROKEN_PIPE straight from ReadFile" , self . handle) ;
596- self . read_buf = self . async . take ( ) . unwrap ( ) . into_inner ( ) . buf ;
611+
612+ let async_data = self . async . take ( ) . unwrap ( ) . into_inner ( ) ;
613+ self . handle = async_data. handle ;
614+ self . read_buf = async_data. buf ;
615+
597616 Err ( WinError :: ChannelClosed )
598617 } ,
599618 Err ( err) => {
600- self . read_buf = self . async . take ( ) . unwrap ( ) . into_inner ( ) . buf ;
619+ let async_data = self . async . take ( ) . unwrap ( ) . into_inner ( ) ;
620+ self . handle = async_data. handle ;
621+ self . read_buf = async_data. buf ;
622+
601623 Err ( WinError :: from_system ( err, "ReadFile" ) )
602624 } ,
603625 }
@@ -621,12 +643,13 @@ impl MessageReader {
621643 /// between receiving the completion notification from the kernel
622644 /// and invoking this method.
623645 unsafe fn notify_completion ( & mut self , io_result : Result < ( ) , WinError > ) -> Result < ( ) , WinError > {
624- win32_trace ! ( "[$ {:?}] notify_completion" , self . handle) ;
646+ win32_trace ! ( "[$ {:?}] notify_completion" , self . async . as_ref ( ) . unwrap ( ) . alias ( ) . handle) ;
625647
626648 // Regardless whether the kernel reported success or error,
627649 // it doesn't have an async read operation in flight at this point anymore.
628650 // (And it's safe again to access the `async` data.)
629651 let async_data = self . async . take ( ) . unwrap ( ) . into_inner ( ) ;
652+ self . handle = async_data. handle ;
630653 let ov = async_data. ov ;
631654 self . read_buf = async_data. buf ;
632655
@@ -677,7 +700,7 @@ impl MessageReader {
677700 BlockingMode :: Blocking => winapi:: TRUE ,
678701 BlockingMode :: Nonblocking => winapi:: FALSE ,
679702 } ;
680- let ok = kernel32:: GetOverlappedResult ( self . handle . as_raw ( ) ,
703+ let ok = kernel32:: GetOverlappedResult ( self . async . as_ref ( ) . unwrap ( ) . alias ( ) . handle . as_raw ( ) ,
681704 self . async . as_mut ( ) . unwrap ( ) . alias_mut ( ) . ov . deref_mut ( ) ,
682705 & mut nbytes,
683706 block) ;
@@ -1405,7 +1428,10 @@ impl OsIpcReceiverSet {
14051428
14061429 // Find the matching receiver
14071430 let ( reader_index, _) = self . readers . iter ( ) . enumerate ( )
1408- . find ( |& ( _, ref reader) | reader. handle . as_raw ( ) as winapi:: ULONG_PTR == completion_key)
1431+ . find ( |& ( _, ref reader) | {
1432+ let raw_handle = reader. async . as_ref ( ) . unwrap ( ) . alias ( ) . handle . as_raw ( ) ;
1433+ raw_handle as winapi:: ULONG_PTR == completion_key
1434+ } )
14091435 . expect ( "Windows IPC ReceiverSet got notification for a receiver it doesn't know about" ) ;
14101436
14111437 // Remove the entry from the set for now -- we will re-add it later,
0 commit comments