@@ -32,6 +32,9 @@ use winapi::{HANDLE, INVALID_HANDLE_VALUE, LPVOID};
3232use kernel32;
3333
3434lazy_static ! {
35+ static ref CURRENT_PROCESS_ID : winapi:: ULONG = unsafe { kernel32:: GetCurrentProcessId ( ) } ;
36+ static ref CURRENT_PROCESS_HANDLE : intptr_t = unsafe { kernel32:: GetCurrentProcess ( ) as intptr_t } ;
37+
3538 static ref DD_ENABLED : bool = match env:: var_os( "DD" ) {
3639 Some ( _) => true ,
3740 None => false ,
@@ -181,7 +184,7 @@ fn dup_handle_to_process_with_flags(handle: HANDLE, other_process: HANDLE, flags
181184
182185 unsafe {
183186 let mut new_handle: HANDLE = INVALID_HANDLE_VALUE ;
184- let ok = kernel32:: DuplicateHandle ( kernel32 :: GetCurrentProcess ( ) , handle,
187+ let ok = kernel32:: DuplicateHandle ( * CURRENT_PROCESS_HANDLE as HANDLE , handle,
185188 other_process, & mut new_handle,
186189 0 , winapi:: FALSE , flags) ;
187190 if ok == winapi:: FALSE {
@@ -276,6 +279,7 @@ impl WinHandle {
276279 WinHandle { h : h }
277280 }
278281
282+ #[ allow( dead_code) ]
279283 fn invalid ( ) -> WinHandle {
280284 WinHandle { h : INVALID_HANDLE_VALUE }
281285 }
@@ -436,7 +440,7 @@ impl MessageReader {
436440 return Ok ( ( ) ) ;
437441 }
438442
439- Err ( WinError :: last ( "ReadFile" ) )
443+ Err ( WinError :: from_system ( err , "ReadFile" ) )
440444 } else {
441445 self . read_in_progress = true ;
442446 Ok ( ( ) )
@@ -498,6 +502,11 @@ impl MessageReader {
498502 assert ! ( msg. channel_is_sender. len( ) == msg. channel_handles. len( ) ) ;
499503 assert ! ( msg. shmem_sizes. len( ) == msg. shmem_handles. len( ) ) ;
500504
505+ dd2 ! ( "[$ {:?}:{:?}] msg with total {} bytes, {} channels, {} shmems, big data handle 0x{:x}" ,
506+ self . iocp, self . handle, data_bytes,
507+ msg. channel_handles. len( ) , msg. shmem_handles. len( ) ,
508+ msg. big_data_receiver_handle) ;
509+
501510 for ( handle, is_sender) in msg. channel_handles . iter ( ) . zip ( msg. channel_is_sender . iter ( ) ) {
502511 channels. push ( OsOpaqueIpcChannel :: new ( * is_sender, * handle as HANDLE ) ) ;
503512 }
@@ -507,8 +516,9 @@ impl MessageReader {
507516 }
508517
509518 if msg. big_data_receiver_handle != 0 {
519+ dd2 ! ( "[$ {:?}:{:?}] read msg with big data, rec handle {:?}" , self . iocp, self . handle, msg. big_data_receiver_handle as HANDLE ) ;
510520 let receiver = OsIpcReceiver :: from_handle ( msg. big_data_receiver_handle as HANDLE ) ;
511- let big_msg = try!( receiver. recv ( ) . map_err ( |_ | panic ! ( "Failed to receive subchannel big data" ) ) ) ;
521+ let big_msg = try!( receiver. recv ( ) . map_err ( |err | panic ! ( "Failed to receive subchannel big data: {:?}" , err ) ) ) ;
512522 buf_data = big_msg. 0 ;
513523 }
514524 }
@@ -561,6 +571,8 @@ impl Drop for OsIpcReceiver {
561571}
562572
563573impl OsIpcReceiver {
574+ // We can't just use an anonymous pipe via CreatePipe(), even though
575+ // that creation is faster -- we a pipe created with FILE_FLAG_OVERLAPPED.
564576 fn new ( ) -> Result < OsIpcReceiver , WinError > {
565577 let mut r = try!( OsIpcReceiver :: new_named ( ) ) ;
566578 let pipe_id = mem:: replace ( & mut r. pipe_id , None ) . unwrap ( ) ;
@@ -580,6 +592,8 @@ impl OsIpcReceiver {
580592
581593 fn new_named ( ) -> Result < OsIpcReceiver , WinError > {
582594 unsafe {
595+ // FIXME make_pipe_id is a big performance cost. We need
596+ // a more efficient way of generating pipe IDs.
583597 let pipe_id = make_pipe_id ( ) ;
584598 let pipe_name = make_pipe_name ( & pipe_id) ;
585599
@@ -871,12 +885,26 @@ impl OsIpcSender {
871885 }
872886 }
873887
874- fn get_pipe_server_process_handle ( & self ) -> Result < WinHandle , WinError > {
888+ fn get_pipe_server_process_id ( & self ) -> Result < winapi :: ULONG , WinError > {
875889 unsafe {
876890 let mut server_pid: winapi:: ULONG = 0 ;
877891 if kernel32:: GetNamedPipeServerProcessId ( * self . handle , & mut server_pid) == winapi:: FALSE {
878892 return Err ( WinError :: last ( "GetNamedPipeServerProcessId" ) ) ;
879893 }
894+ Ok ( server_pid)
895+ }
896+ }
897+
898+ // TODO(vlad): if we could guarantee that a server handle can't be passed
899+ // after it's already been used to start receiving data, we could
900+ // store the server handle instead of needing to look it up each time.
901+ fn get_pipe_server_process_handle ( & self ) -> Result < WinHandle , WinError > {
902+ unsafe {
903+ let server_pid = try!( self . get_pipe_server_process_id ( ) ) ;
904+ if server_pid == * CURRENT_PROCESS_ID {
905+ return Ok ( WinHandle :: new ( * CURRENT_PROCESS_HANDLE as HANDLE ) ) ;
906+ }
907+
880908 let raw_handle = kernel32:: OpenProcess ( winapi:: PROCESS_DUP_HANDLE ,
881909 winapi:: FALSE ,
882910 server_pid as winapi:: DWORD ) ;
@@ -903,12 +931,17 @@ impl OsIpcSender {
903931 // creates.
904932 fn send_unfragmented ( & self , data : & [ u8 ] ) -> Result < ( ) , WinError > {
905933 assert ! ( data. len( ) < INVALID_HEADER_DATA_SIZE as usize ) ;
934+
935+ dd2 ! ( "[c {:?}] writing unfragmented to (pid {}->{})" , * self . handle, * CURRENT_PROCESS_ID ,
936+ try!( self . get_pipe_server_process_id( ) ) ) ;
937+
906938 unsafe {
907939 let header: [ u32 ; 2 ] = [ data. len ( ) as u32 , 0 ] ;
908940 let header_bytes: & [ u8 ] = slice:: from_raw_parts ( header. as_ptr ( ) as * const u8 , HEADER_SIZE ) ;
909941 try!( write_buf ( * self . handle , & header_bytes) ) ;
910942 try!( write_buf ( * self . handle , data) ) ;
911943 }
944+ dd2 ! ( "[c {:?}] sent unfragmented: {} bytes" , * self . handle, data. len( ) ) ;
912945 Ok ( ( ) )
913946 }
914947
@@ -976,7 +1009,10 @@ impl OsIpcSender {
9761009 unsafe {
9771010 // if we need to use the fragment channel, then we send a 0 as the data size;
9781011 // the receiver will see that there's a big data receiver in the OOB portion
979- let header: [ u32 ; 2 ] = [ if big_data_sender. is_some ( ) { 0 } else { data. len ( ) } as u32 , oob_data. len ( ) as u32 ] ;
1012+ let header: [ u32 ; 2 ] = [
1013+ if big_data_sender. is_some ( ) { 0 } else { data. len ( ) } as u32 ,
1014+ oob_data. len ( ) as u32
1015+ ] ;
9801016 let header_bytes: & [ u8 ] = slice:: from_raw_parts ( header. as_ptr ( ) as * const u8 , HEADER_SIZE ) ;
9811017
9821018 // We need to write the main message first, which will indicate to the receiver
@@ -988,6 +1024,8 @@ impl OsIpcSender {
9881024 }
9891025 try!( write_buf ( * self . handle , & oob_data) ) ;
9901026 if big_data_sender. is_some ( ) {
1027+ dd2 ! ( "[c {:?}] sending unfragmented to big-data channel: {} bytes" ,
1028+ * self . handle, data. len( ) ) ;
9911029 try!( big_data_sender. unwrap ( ) . send_unfragmented ( data) ) ;
9921030 }
9931031 }
@@ -1435,7 +1473,6 @@ impl From<WinError> for DeserializeError {
14351473
14361474impl From < WinError > for Error {
14371475 fn from ( mpsc_error : WinError ) -> Error {
1438- //Error::new(ErrorKind::Other, format!("Win channel error ({} from {})", mpsc_error.0, mpsc_error.1))
1439- Error :: new ( ErrorKind :: Other , format ! ( "Win channel error ({})" , mpsc_error. 0 ) )
1476+ Error :: new ( ErrorKind :: Other , format ! ( "Win channel error ({}=0x{:x})" , mpsc_error. 0 , mpsc_error. 0 ) )
14401477 }
14411478}
0 commit comments