@@ -31,15 +31,10 @@ use winapi;
3131use winapi:: { HANDLE , INVALID_HANDLE_VALUE , LPVOID } ;
3232use kernel32;
3333
34+ // some debug bump macros to better track what's going on in case of errors
3435lazy_static ! {
35- static ref DD_ENABLED : bool = match env:: var_os( "DD" ) {
36- Some ( _) => true ,
37- None => false ,
38- } ;
39- static ref DD2_ENABLED : bool = match env:: var_os( "DD2" ) {
40- Some ( _) => true ,
41- None => false ,
42- } ;
36+ static ref DD_ENABLED : bool = env:: var_os( "IPC_CHANNEL_WIN_DEBUG_DUMP" ) . is_some( ) ;
37+ static ref DD2_ENABLED : bool = env:: var_os( "IPC_CHANNEL_WIN_DEBUG_MORE_DUMP" ) . is_some( ) ;
4338}
4439
4540macro_rules! dd { ( $( $rest: tt) * ) => { if * DD_ENABLED { println!( $( $rest) * ) ; } } }
@@ -108,8 +103,8 @@ impl OsIpcOutOfBandMessage {
108103 }
109104
110105 fn needs_to_be_sent ( & self ) -> bool {
111- self . channel_handles . len ( ) > 0 ||
112- self . shmem_handles . len ( ) > 0 ||
106+ ! self . channel_handles . is_empty ( ) ||
107+ ! self . shmem_handles . is_empty ( ) ||
113108 self . big_data_receiver_handle != 0
114109 }
115110
@@ -374,7 +369,8 @@ impl MessageReader {
374369
375370 // if the remote end closed...
376371 if err != winapi:: ERROR_SUCCESS {
377- panic ! ( "[$ {:?}:{:?}] *** notify_completion: need to handle error! {}" , self . iocp, self . handle, err) ;
372+ // This should never happen
373+ panic ! ( "[$ {:?}:{:?}] *** notify_completion: unhandled error reported! {}" , self . iocp, self . handle, err) ;
378374 }
379375
380376 unsafe {
@@ -395,17 +391,18 @@ impl MessageReader {
395391 }
396392
397393 dd2 ! ( "[$ {:?}:{:?}] start_read ov {:?}" , self . iocp, self . handle, self . ov_ptr( ) ) ;
398- let mut bytes_read: u32 = 0 ;
399394
400- // if the buffer is full, add more space
401395 let buf_len = self . read_buf . len ( ) ;
402396 let mut buf_cap = self . read_buf . capacity ( ) ;
397+ let mut bytes_read: u32 = 0 ;
398+
399+ // if the buffer is full, add more capacity
403400 if buf_cap == buf_len {
404- let more =
405- if buf_cap == 0 { READ_BUFFER_SIZE }
406- else if buf_cap < READ_BUFFER_MAX_GROWTH { buf_cap }
407- else { READ_BUFFER_MAX_GROWTH } ;
408- self . read_buf . reserve ( more ) ;
401+ self . read_buf . reserve ( match buf_cap {
402+ 0 => READ_BUFFER_SIZE ,
403+ 1 ... READ_BUFFER_MAX_GROWTH => buf_cap,
404+ _ => READ_BUFFER_MAX_GROWTH
405+ } ) ;
409406 buf_cap = self . read_buf . capacity ( ) ;
410407 }
411408
@@ -463,8 +460,8 @@ impl MessageReader {
463460
464461 // Err(false) -> something really failed
465462 // Err(true) -> no message
466- // XXX This is dumb, we should return
467- // Result<Option<(...)>,WinError>
463+ // FIXME This is dumb, we should probably make this return Result<Option<(...)>,WinError>
464+ // so that we can pass through the error that's lost in map_err below
468465 fn get_message ( & mut self ) -> Result < ( Vec < u8 > , Vec < OsOpaqueIpcChannel > , Vec < OsIpcSharedMemory > ) , bool > {
469466 let message_lengths = self . message_length ( ) ;
470467 if message_lengths. is_none ( ) {
@@ -476,7 +473,6 @@ impl MessageReader {
476473
477474 // remove this message's bytes from read_buf, or just take read_buf
478475 // if it contains exactly one message
479- //dd!("[$ {:?}:{:?}] rb {:?}", self.iocp, self.handle, self.read_buf);
480476 let msg_buf = if self . read_buf . len ( ) == bytes_needed {
481477 mem:: replace ( & mut self . read_buf , Vec :: with_capacity ( READ_BUFFER_SIZE ) )
482478 } else {
@@ -515,7 +511,6 @@ impl MessageReader {
515511
516512 dd ! ( "[$ {:?}:{:?}] get_message success -> {} bytes, {} channels, {} shmems" ,
517513 self . iocp, self . handle, buf_data. len( ) , channels. len( ) , shmems. len( ) ) ;
518- //dd!("[$ {:?}:{:?}] bd {:?}", self.iocp, self.handle, buf_data);
519514 Ok ( ( buf_data, channels, shmems) )
520515 }
521516}
@@ -621,7 +616,7 @@ impl OsIpcReceiver {
621616 // cancel any outstanding IO request
622617 reader. cancel_io ( ) ;
623618 // this is only okay if we have nothing in the read buf
624- Ok ( reader. read_buf . len ( ) == 0 )
619+ Ok ( reader. read_buf . is_empty ( ) )
625620 }
626621
627622 pub fn consume ( & self ) -> OsIpcReceiver {
@@ -719,7 +714,7 @@ impl OsIpcReceiver {
719714 iocp,
720715 * self . handle as winapi:: ULONG_PTR ,
721716 0 ) ;
722- if ret == ptr :: null_mut ( ) {
717+ if ret. is_null ( ) {
723718 return Err ( WinError :: last ( "CreateIoCompletionPort" ) ) ;
724719 }
725720
@@ -811,7 +806,6 @@ unsafe fn write_buf(handle: HANDLE, bytes: &[u8]) -> Result<(),WinError> {
811806 return Ok ( ( ) ) ;
812807 }
813808 let mut nwritten: u32 = 0 ;
814- //dd!("[c {:?}] writing: {:?}", handle, bytes);
815809 while nwritten < ntowrite {
816810 let mut nwrote: u32 = 0 ;
817811 if kernel32:: WriteFile ( handle,
@@ -825,7 +819,7 @@ unsafe fn write_buf(handle: HANDLE, bytes: &[u8]) -> Result<(),WinError> {
825819 }
826820 nwritten += nwrote;
827821 ntowrite -= nwrote;
828- //dd !("[c {:?}] ... wrote {} bytes, total {}/{} err {}", handle, nwrote, nwritten, bytes.len(), GetLastError());
822+ dd2 ! ( "[c {:?}] ... wrote {} bytes, total {}/{} err {}" , handle, nwrote, nwritten, bytes. len( ) , GetLastError ( ) ) ;
829823 }
830824
831825 Ok ( ( ) )
@@ -880,7 +874,7 @@ impl OsIpcSender {
880874 let raw_handle = kernel32:: OpenProcess ( winapi:: PROCESS_DUP_HANDLE ,
881875 winapi:: FALSE ,
882876 server_pid as winapi:: DWORD ) ;
883- if raw_handle == ptr :: null_mut ( ) {
877+ if raw_handle. is_null ( ) {
884878 return Err ( WinError :: last ( "OpenProcess" ) ) ;
885879 }
886880
@@ -924,7 +918,7 @@ impl OsIpcSender {
924918 assert ! ( data. len( ) < INVALID_HEADER_DATA_SIZE as usize ) ;
925919
926920 let server_process_handle =
927- if ports. len ( ) > 0 || shared_memory_regions. len ( ) > 0 {
921+ if ! ports. is_empty ( ) || ! shared_memory_regions. is_empty ( ) {
928922 try!( self . get_pipe_server_process_handle ( ) )
929923 } else {
930924 WinHandle :: invalid ( )
@@ -1016,7 +1010,7 @@ impl OsIpcReceiverSet {
10161010 ptr:: null_mut ( ) ,
10171011 0 as winapi:: ULONG_PTR ,
10181012 0 ) ;
1019- if iocp == ptr :: null_mut ( ) {
1013+ if iocp. is_null ( ) {
10201014 return Err ( WinError :: last ( "CreateIoCompletionPort" ) ) ;
10211015 }
10221016
@@ -1031,9 +1025,18 @@ impl OsIpcReceiverSet {
10311025 // use this to identify the receiver
10321026 let receiver_handle = * receiver. handle ;
10331027
1034- // XXX we'll need a mutex here... at least while we loop through
1035- // receivers to find a matching handle when we get a IOCP
10361028 try!( receiver. add_to_iocp ( * self . iocp ) ) ;
1029+
1030+ // FIXME we *may* need a mutex to protect self.receivers --
1031+ // one thread could be adding something to this Set while
1032+ // another is calling select(); the add() could cause the
1033+ // receivers array to reallocate while we're doing stuff with
1034+ // it in select(). That would mean an add() would block while
1035+ // a select() is blocking.
1036+ //
1037+ // A better option would be to have a mutex around a
1038+ // self.receivers_to_add array, and have select drain those
1039+ // and append to self.receivers whenever it's called.
10371040 self . receivers . push ( receiver) ;
10381041
10391042 dd ! ( "[# {:?}] ReceiverSet add {:?}" , * self . iocp, receiver_handle) ;
@@ -1042,7 +1045,7 @@ impl OsIpcReceiverSet {
10421045 }
10431046
10441047 pub fn select ( & mut self ) -> Result < Vec < OsIpcSelectionResult > , WinError > {
1045- assert ! ( self . receivers. len ( ) > 0 , "selecting with no objects?" ) ;
1048+ assert ! ( ! self . receivers. is_empty ( ) , "selecting with no objects?" ) ;
10461049 dd ! ( "[# {:?}] select() with {} receivers" , * self . iocp, self . receivers. len( ) ) ;
10471050
10481051 unsafe {
@@ -1068,7 +1071,7 @@ impl OsIpcReceiverSet {
10681071 } ) ;
10691072
10701073 // if we had prematurely closed elements, just process them first
1071- if selection_results. len ( ) > 0 {
1074+ if ! selection_results. is_empty ( ) {
10721075 return Ok ( selection_results) ;
10731076 }
10741077
@@ -1091,7 +1094,7 @@ impl OsIpcReceiverSet {
10911094 // function call itself failed or timed out.
10921095 // Otherwise, the async IO operation failed, and
10931096 // we want to hand io_err to notify_completion below.
1094- if ov_ptr == ptr :: null_mut ( ) {
1097+ if ov_ptr. is_null ( ) {
10951098 return Err ( WinError :: last ( "GetQueuedCompletionStatus" ) ) ;
10961099 }
10971100
@@ -1153,7 +1156,7 @@ impl OsIpcReceiverSet {
11531156
11541157 // if we didn't dequeue at least one complete message -- we need to loop through GetQueuedCS again;
11551158 // otherwise we're done.
1156- if selection_results. len ( ) > 0 {
1159+ if ! selection_results. is_empty ( ) {
11571160 break ;
11581161 }
11591162 }
@@ -1263,7 +1266,7 @@ impl OsIpcSharedMemory {
12631266 winapi:: FILE_MAP_ALL_ACCESS ,
12641267 0 , 0 , 0 )
12651268 } ;
1266- if address == ptr :: null_mut ( ) {
1269+ if address. is_null ( ) {
12671270 return Err ( WinError :: last ( "MapViewOfFile" ) ) ;
12681271 }
12691272
@@ -1435,7 +1438,6 @@ impl From<WinError> for DeserializeError {
14351438
14361439impl From < WinError > for Error {
14371440 fn from ( mpsc_error : WinError ) -> Error {
1438- //Error::new(ErrorKind::Other, format!("Win channel error ({} from {})", mpsc_error.0, mpsc_error.1))
14391441 Error :: new ( ErrorKind :: Other , format ! ( "Win channel error ({})" , mpsc_error. 0 ) )
14401442 }
14411443}
0 commit comments