@@ -32,6 +32,9 @@ use winapi::{HANDLE, INVALID_HANDLE_VALUE, LPVOID};
32
32
use kernel32;
33
33
34
34
lazy_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
+
35
38
static ref DD_ENABLED : bool = match env:: var_os( "DD" ) {
36
39
Some ( _) => true ,
37
40
None => false ,
@@ -181,7 +184,7 @@ fn dup_handle_to_process_with_flags(handle: HANDLE, other_process: HANDLE, flags
181
184
182
185
unsafe {
183
186
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,
185
188
other_process, & mut new_handle,
186
189
0 , winapi:: FALSE , flags) ;
187
190
if ok == winapi:: FALSE {
@@ -276,6 +279,7 @@ impl WinHandle {
276
279
WinHandle { h : h }
277
280
}
278
281
282
+ #[ allow( dead_code) ]
279
283
fn invalid ( ) -> WinHandle {
280
284
WinHandle { h : INVALID_HANDLE_VALUE }
281
285
}
@@ -436,7 +440,7 @@ impl MessageReader {
436
440
return Ok ( ( ) ) ;
437
441
}
438
442
439
- Err ( WinError :: last ( "ReadFile" ) )
443
+ Err ( WinError :: from_system ( err , "ReadFile" ) )
440
444
} else {
441
445
self . read_in_progress = true ;
442
446
Ok ( ( ) )
@@ -498,6 +502,11 @@ impl MessageReader {
498
502
assert ! ( msg. channel_is_sender. len( ) == msg. channel_handles. len( ) ) ;
499
503
assert ! ( msg. shmem_sizes. len( ) == msg. shmem_handles. len( ) ) ;
500
504
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
+
501
510
for ( handle, is_sender) in msg. channel_handles . iter ( ) . zip ( msg. channel_is_sender . iter ( ) ) {
502
511
channels. push ( OsOpaqueIpcChannel :: new ( * is_sender, * handle as HANDLE ) ) ;
503
512
}
@@ -507,8 +516,9 @@ impl MessageReader {
507
516
}
508
517
509
518
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 ) ;
510
520
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 ) ) ) ;
512
522
buf_data = big_msg. 0 ;
513
523
}
514
524
}
@@ -561,6 +571,8 @@ impl Drop for OsIpcReceiver {
561
571
}
562
572
563
573
impl 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.
564
576
fn new ( ) -> Result < OsIpcReceiver , WinError > {
565
577
let mut r = try!( OsIpcReceiver :: new_named ( ) ) ;
566
578
let pipe_id = mem:: replace ( & mut r. pipe_id , None ) . unwrap ( ) ;
@@ -580,6 +592,8 @@ impl OsIpcReceiver {
580
592
581
593
fn new_named ( ) -> Result < OsIpcReceiver , WinError > {
582
594
unsafe {
595
+ // FIXME make_pipe_id is a big performance cost. We need
596
+ // a more efficient way of generating pipe IDs.
583
597
let pipe_id = make_pipe_id ( ) ;
584
598
let pipe_name = make_pipe_name ( & pipe_id) ;
585
599
@@ -871,12 +885,26 @@ impl OsIpcSender {
871
885
}
872
886
}
873
887
874
- fn get_pipe_server_process_handle ( & self ) -> Result < WinHandle , WinError > {
888
+ fn get_pipe_server_process_id ( & self ) -> Result < winapi :: ULONG , WinError > {
875
889
unsafe {
876
890
let mut server_pid: winapi:: ULONG = 0 ;
877
891
if kernel32:: GetNamedPipeServerProcessId ( * self . handle , & mut server_pid) == winapi:: FALSE {
878
892
return Err ( WinError :: last ( "GetNamedPipeServerProcessId" ) ) ;
879
893
}
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
+
880
908
let raw_handle = kernel32:: OpenProcess ( winapi:: PROCESS_DUP_HANDLE ,
881
909
winapi:: FALSE ,
882
910
server_pid as winapi:: DWORD ) ;
@@ -903,12 +931,17 @@ impl OsIpcSender {
903
931
// creates.
904
932
fn send_unfragmented ( & self , data : & [ u8 ] ) -> Result < ( ) , WinError > {
905
933
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
+
906
938
unsafe {
907
939
let header: [ u32 ; 2 ] = [ data. len ( ) as u32 , 0 ] ;
908
940
let header_bytes: & [ u8 ] = slice:: from_raw_parts ( header. as_ptr ( ) as * const u8 , HEADER_SIZE ) ;
909
941
try!( write_buf ( * self . handle , & header_bytes) ) ;
910
942
try!( write_buf ( * self . handle , data) ) ;
911
943
}
944
+ dd2 ! ( "[c {:?}] sent unfragmented: {} bytes" , * self . handle, data. len( ) ) ;
912
945
Ok ( ( ) )
913
946
}
914
947
@@ -976,7 +1009,10 @@ impl OsIpcSender {
976
1009
unsafe {
977
1010
// if we need to use the fragment channel, then we send a 0 as the data size;
978
1011
// 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
+ ] ;
980
1016
let header_bytes: & [ u8 ] = slice:: from_raw_parts ( header. as_ptr ( ) as * const u8 , HEADER_SIZE ) ;
981
1017
982
1018
// We need to write the main message first, which will indicate to the receiver
@@ -988,6 +1024,8 @@ impl OsIpcSender {
988
1024
}
989
1025
try!( write_buf ( * self . handle , & oob_data) ) ;
990
1026
if big_data_sender. is_some ( ) {
1027
+ dd2 ! ( "[c {:?}] sending unfragmented to big-data channel: {} bytes" ,
1028
+ * self . handle, data. len( ) ) ;
991
1029
try!( big_data_sender. unwrap ( ) . send_unfragmented ( data) ) ;
992
1030
}
993
1031
}
@@ -1435,7 +1473,6 @@ impl From<WinError> for DeserializeError {
1435
1473
1436
1474
impl From < WinError > for Error {
1437
1475
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 ) )
1440
1477
}
1441
1478
}
0 commit comments