@@ -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`,
@@ -460,7 +472,7 @@ impl MessageReader {
460472 /// and the caller should not attempt waiting for completion.
461473 fn issue_async_cancel ( & mut self ) {
462474 unsafe {
463- let status = kernel32:: CancelIoEx ( self . handle . as_raw ( ) ,
475+ let status = kernel32:: CancelIoEx ( self . async . as_ref ( ) . unwrap ( ) . alias ( ) . handle . as_raw ( ) ,
464476 self . async . as_mut ( ) . unwrap ( ) . alias_mut ( ) . ov . deref_mut ( ) ) ;
465477
466478 if status == winapi:: FALSE {
@@ -480,7 +492,9 @@ impl MessageReader {
480492 // and the caller should not attempt to wait for completion.
481493 assert ! ( GetLastError ( ) == winapi:: ERROR_NOT_FOUND ) ;
482494
483- self . read_buf = self . async . take ( ) . unwrap ( ) . into_inner ( ) . buf ;
495+ let async_data = self . async . take ( ) . unwrap ( ) . into_inner ( ) ;
496+ self . handle = async_data. handle ;
497+ self . read_buf = async_data. buf ;
484498 }
485499 }
486500 }
@@ -537,14 +551,15 @@ impl MessageReader {
537551
538552 // issue the read to the buffer, at the current length offset
539553 self . async = Some ( AliasedCell :: new ( AsyncData {
554+ handle : self . handle . take ( ) ,
540555 ov : Box :: new ( mem:: zeroed ( ) ) ,
541556 buf : mem:: replace ( & mut self . read_buf , vec ! [ ] ) ,
542557 } ) ) ;
543558 let mut bytes_read: u32 = 0 ;
544559 let ok = {
545560 let async_data = self . async . as_mut ( ) . unwrap ( ) . alias_mut ( ) ;
546561 let remaining_buf = & mut async_data. buf [ buf_len..] ;
547- kernel32:: ReadFile ( self . handle . as_raw ( ) ,
562+ kernel32:: ReadFile ( async_data . handle . as_raw ( ) ,
548563 remaining_buf. as_mut_ptr ( ) as LPVOID ,
549564 remaining_buf. len ( ) as u32 ,
550565 & mut bytes_read,
@@ -587,11 +602,18 @@ impl MessageReader {
587602 } ,
588603 Err ( winapi:: ERROR_BROKEN_PIPE ) => {
589604 win32_trace ! ( "[$ {:?}] BROKEN_PIPE straight from ReadFile" , self . handle) ;
590- self . read_buf = self . async . take ( ) . unwrap ( ) . into_inner ( ) . buf ;
605+
606+ let async_data = self . async . take ( ) . unwrap ( ) . into_inner ( ) ;
607+ self . handle = async_data. handle ;
608+ self . read_buf = async_data. buf ;
609+
591610 Err ( WinError :: ChannelClosed )
592611 } ,
593612 Err ( err) => {
594- self . read_buf = self . async . take ( ) . unwrap ( ) . into_inner ( ) . buf ;
613+ let async_data = self . async . take ( ) . unwrap ( ) . into_inner ( ) ;
614+ self . handle = async_data. handle ;
615+ self . read_buf = async_data. buf ;
616+
595617 Err ( WinError :: from_system ( err, "ReadFile" ) )
596618 } ,
597619 }
@@ -615,12 +637,13 @@ impl MessageReader {
615637 /// between receiving the completion notification from the kernel
616638 /// and invoking this method.
617639 unsafe fn notify_completion ( & mut self , io_result : Result < ( ) , WinError > ) -> Result < ( ) , WinError > {
618- win32_trace ! ( "[$ {:?}] notify_completion" , self . handle) ;
640+ win32_trace ! ( "[$ {:?}] notify_completion" , self . async . as_ref ( ) . unwrap ( ) . alias ( ) . handle) ;
619641
620642 // Regardless whether the kernel reported success or error,
621643 // it doesn't have an async read operation in flight at this point anymore.
622644 // (And it's safe again to access the `async` data.)
623645 let async_data = self . async . take ( ) . unwrap ( ) . into_inner ( ) ;
646+ self . handle = async_data. handle ;
624647 let ov = async_data. ov ;
625648 self . read_buf = async_data. buf ;
626649
@@ -671,7 +694,7 @@ impl MessageReader {
671694 BlockingMode :: Blocking => winapi:: TRUE ,
672695 BlockingMode :: Nonblocking => winapi:: FALSE ,
673696 } ;
674- let ok = kernel32:: GetOverlappedResult ( self . handle . as_raw ( ) ,
697+ let ok = kernel32:: GetOverlappedResult ( self . async . as_ref ( ) . unwrap ( ) . alias ( ) . handle . as_raw ( ) ,
675698 self . async . as_mut ( ) . unwrap ( ) . alias_mut ( ) . ov . deref_mut ( ) ,
676699 & mut nbytes,
677700 block) ;
@@ -1399,7 +1422,10 @@ impl OsIpcReceiverSet {
13991422
14001423 // Find the matching receiver
14011424 let ( reader_index, _) = self . readers . iter ( ) . enumerate ( )
1402- . find ( |& ( _, ref reader) | reader. handle . as_raw ( ) as winapi:: ULONG_PTR == completion_key)
1425+ . find ( |& ( _, ref reader) | {
1426+ let raw_handle = reader. async . as_ref ( ) . unwrap ( ) . alias ( ) . handle . as_raw ( ) ;
1427+ raw_handle as winapi:: ULONG_PTR == completion_key
1428+ } )
14031429 . expect ( "Windows IPC ReceiverSet got notification for a receiver it doesn't know about" ) ;
14041430
14051431 // Remove the entry from the set for now -- we will re-add it later,
0 commit comments