@@ -34,21 +34,22 @@ lazy_static! {
3434 static ref DEBUG_TRACE_ENABLED : bool = { env:: var_os( "IPC_CHANNEL_WIN_DEBUG_TRACE" ) . is_some( ) } ;
3535}
3636
37- // some debug bump macros to better track what's going on in case of errors
37+ /// Debug macro to better track what's going on in case of errors.
3838macro_rules! win32_trace { ( $( $rest: tt) * ) => {
3939 if cfg!( feature = "win32-trace" ) {
4040 if * DEBUG_TRACE_ENABLED { println!( $( $rest) * ) ; }
4141 }
4242} }
4343
44- // When we create the pipe, how big of a write buffer do we specify?
45- // This is reserved in the nonpaged pool. The fragment size is the
46- // max we can write to the pipe without fragmentation, and the
47- // buffer size is what we tell the pipe it is, so we have room
48- // for out of band data etc.
44+ /// When we create the pipe, how big of a write buffer do we specify?
45+ ///
46+ /// This is reserved in the nonpaged pool. The fragment size is the
47+ /// max we can write to the pipe without fragmentation, and the
48+ /// buffer size is what we tell the pipe it is, so we have room
49+ /// for out of band data etc.
4950const MAX_FRAGMENT_SIZE : usize = 64 * 1024 ;
5051
51- // Size of the pipe's write buffer, with excess room for the header.
52+ /// Size of the pipe's write buffer, with excess room for the header.
5253const PIPE_BUFFER_SIZE : usize = MAX_FRAGMENT_SIZE + 4 * 1024 ;
5354
5455#[ allow( non_snake_case) ]
@@ -68,7 +69,7 @@ pub fn channel() -> Result<(OsIpcSender, OsIpcReceiver),WinError> {
6869 Ok ( ( sender, receiver) )
6970}
7071
71- // Holds data len and out-of-band data len
72+ /// Holds data len and out-of-band data len.
7273struct MessageHeader ( u32 , u32 ) ;
7374
7475impl MessageHeader {
@@ -138,26 +139,26 @@ impl<'data> Message<'data> {
138139 }
139140}
140141
141- // If we have any channel handles or shmem segments, then we'll send an
142- // OutOfBandMessage after the data message.
143- //
144- // This includes the receiver's process ID, which the receiver checks to
145- // make sure that the message was originally sent to it, and was not sitting
146- // in another channel's buffer when that channel got transferred to another
147- // process. On Windows, we duplicate handles on the sender side to a specific
148- // reciever. If the wrong receiver gets it, those handles are not valid.
149- //
150- // TODO(vlad): We could attempt to recover from the above situation by
151- // duplicating from the intended target process to ourselves (the receiver).
152- // That would only work if the intended process a) still exists; b) can be
153- // opened by the receiver with handle dup privileges. Another approach
154- // could be to use a separate dedicated process intended purely for handle
155- // passing, though that process would need to be global to any processes
156- // amongst which you want to share channels or connect one-shot servers to.
157- // There may be a system process that we could use for this purpose, but
158- // I haven't foundone -- and in the system process case, we'd need to ensure
159- // that we don't leak the handles (e.g. dup a handle to the system process,
160- // and then everything dies -- we don't want those resources to be leaked).
142+ /// If we have any channel handles or shmem segments, then we'll send an
143+ /// OutOfBandMessage after the data message.
144+ ///
145+ /// This includes the receiver's process ID, which the receiver checks to
146+ /// make sure that the message was originally sent to it, and was not sitting
147+ /// in another channel's buffer when that channel got transferred to another
148+ /// process. On Windows, we duplicate handles on the sender side to a specific
149+ /// reciever. If the wrong receiver gets it, those handles are not valid.
150+ ///
151+ /// TODO(vlad): We could attempt to recover from the above situation by
152+ /// duplicating from the intended target process to ourselves (the receiver).
153+ /// That would only work if the intended process a) still exists; b) can be
154+ /// opened by the receiver with handle dup privileges. Another approach
155+ /// could be to use a separate dedicated process intended purely for handle
156+ /// passing, though that process would need to be global to any processes
157+ /// amongst which you want to share channels or connect one-shot servers to.
158+ /// There may be a system process that we could use for this purpose, but
159+ /// I haven't foundone -- and in the system process case, we'd need to ensure
160+ /// that we don't leak the handles (e.g. dup a handle to the system process,
161+ /// and then everything dies -- we don't want those resources to be leaked).
161162#[ derive( Debug ) ]
162163struct OutOfBandMessage {
163164 target_process_id : u32 ,
@@ -217,11 +218,11 @@ fn make_pipe_name(pipe_id: &Uuid) -> CString {
217218 CString :: new ( format ! ( "\\ \\ .\\ pipe\\ rust-ipc-{}" , pipe_id. to_string( ) ) ) . unwrap ( )
218219}
219220
220- // Duplicate a given handle from this process to the target one, passing the
221- // given flags to DuplicateHandle.
222- //
223- // Unlike win32 DuplicateHandle, this will preserve INVALID_HANDLE_VALUE (which is
224- // also the pseudohandle for the current process).
221+ /// Duplicate a given handle from this process to the target one, passing the
222+ /// given flags to DuplicateHandle.
223+ ///
224+ /// Unlike win32 DuplicateHandle, this will preserve INVALID_HANDLE_VALUE (which is
225+ /// also the pseudohandle for the current process).
225226unsafe fn dup_handle_to_process_with_flags ( handle : HANDLE , other_process : HANDLE , flags : winapi:: DWORD )
226227 -> Result < HANDLE , WinError >
227228{
@@ -240,12 +241,12 @@ unsafe fn dup_handle_to_process_with_flags(handle: HANDLE, other_process: HANDLE
240241 }
241242}
242243
243- // duplicate a handle in the current process
244+ /// Duplicate a handle in the current process.
244245fn dup_handle ( handle : & WinHandle ) -> Result < WinHandle , WinError > {
245246 dup_handle_to_process ( handle, & WinHandle :: new ( * CURRENT_PROCESS_HANDLE as HANDLE ) )
246247}
247248
248- // duplicate a handle to the target process
249+ /// Duplicate a handle to the target process.
249250fn dup_handle_to_process ( handle : & WinHandle , other_process : & WinHandle ) -> Result < WinHandle , WinError > {
250251 unsafe {
251252 let h = try!( dup_handle_to_process_with_flags (
@@ -254,7 +255,7 @@ fn dup_handle_to_process(handle: &WinHandle, other_process: &WinHandle) -> Resul
254255 }
255256}
256257
257- // duplicate a handle to the target process, closing the source handle
258+ /// Duplicate a handle to the target process, closing the source handle.
258259fn move_handle_to_process ( handle : & mut WinHandle , other_process : & WinHandle ) -> Result < WinHandle , WinError > {
259260 unsafe {
260261 let h = try!( dup_handle_to_process_with_flags (
@@ -334,29 +335,32 @@ enum GetMessageResult {
334335 Message ( Vec < u8 > , Vec < OsOpaqueIpcChannel > , Vec < OsIpcSharedMemory > ) ,
335336}
336337
337- // MessageReader implements blocking/nonblocking reads of messages
338- // from the handle
338+ /// Main object keeping track of a receive handle and its associated state.
339+ ///
340+ /// Implements blocking/nonblocking reads of messages from the handle.
339341#[ derive( Debug ) ]
340342struct MessageReader {
341- // The pipe read handle
343+ /// The pipe read handle.
342344 handle : WinHandle ,
343345
344- // The OVERLAPPED struct for async IO on this receiver; we'll only
345- // ever have one in flight
346+ /// The OVERLAPPED struct for async IO on this receiver.
347+ ///
348+ /// We'll only ever have one in flight.
346349 ov : Box < winapi:: OVERLAPPED > ,
347350
348- // A read buffer for any pending reads
351+ /// A read buffer for any pending reads.
349352 read_buf : Vec < u8 > ,
350353
351- // If we have already issued an async read
354+ /// Whether we have already issued an async read.
352355 read_in_progress : bool ,
353356
354- // If we received a BROKEN_PIPE or other error
355- // indicating that the remote end has closed the pipe
357+ /// Whether we received a BROKEN_PIPE or other error
358+ /// indicating that the remote end has closed the pipe.
356359 closed : bool ,
357360
358- // If this is part of a Set, then this is the ID that is used to identify
359- // this reader. If this is None, then this isn't part of a set.
361+ /// ID identifying this reader within a receiver set.
362+ ///
363+ /// `None` if the `MessageReader` is not part of any set.
360364 set_id : Option < u64 > ,
361365}
362366
@@ -381,7 +385,7 @@ impl MessageReader {
381385 }
382386 }
383387
384- // Called when we receive an IO Completion Packet for this handle.
388+ /// Called when we receive an IO Completion Packet for this handle.
385389 fn notify_completion ( & mut self , err : u32 ) -> Result < ( ) , WinError > {
386390 win32_trace ! ( "[$ {:?}] notify_completion" , self . handle) ;
387391
@@ -558,9 +562,12 @@ impl MessageReader {
558562 }
559563 }
560564
561- // This is a specialized read when the buffser size is known ahead of time,
562- // and without our typical message framing. It's only valid to call this
563- // as the one and only call after creating a MessageReader.
565+ /// Specialized read for out-of-band data ports.
566+ ///
567+ /// Here the buffer size is known in advance,
568+ /// and the transfer doesn't have our typical message framing.
569+ ///
570+ /// It's only valid to call this as the one and only call after creating a MessageReader.
564571 fn read_raw_sized ( & mut self , size : usize ) -> Result < Vec < u8 > , WinError > {
565572 assert ! ( self . read_buf. len( ) == 0 ) ;
566573
@@ -610,8 +617,12 @@ impl MessageReader {
610617
611618#[ derive( Debug ) ]
612619pub struct OsIpcReceiver {
613- // A MessageReader that implements most of the work of this
614- // MessageReader
620+ /// The receive handle and its associated state.
621+ ///
622+ /// We can't just deal with raw handles like in the other platform back-ends,
623+ /// since this implementation -- using plain pipes with no native packet handling --
624+ /// requires keeping track of various bits of receiver state,
625+ /// which must not be separated from the handle itself.
615626 reader : RefCell < MessageReader > ,
616627}
617628
@@ -744,7 +755,9 @@ impl OsIpcReceiver {
744755 self . receive_message ( false )
745756 }
746757
747- // Do a pipe connect. Only used for one-shot servers
758+ /// Do a pipe connect.
759+ ///
760+ /// Only used for one-shot servers.
748761 fn accept ( & mut self ) -> Result < ( ) , WinError > {
749762 unsafe {
750763 let reader_borrow = self . reader . borrow ( ) ;
@@ -792,17 +805,17 @@ impl OsIpcReceiver {
792805 }
793806 }
794807
795- // Does a single explicitly-sized recv from the handle, consuming
796- // the receiver in the process. This is used for receiving data
797- // from the out-of-band big data buffer.
808+ /// Does a single explicitly-sized recv from the handle,
809+ /// consuming the receiver in the process.
810+ ///
811+ /// This is used for receiving data from the out-of-band big data buffer.
798812 fn recv_raw ( self , size : usize ) -> Result < Vec < u8 > , WinError > {
799813 self . reader . borrow_mut ( ) . read_raw_sized ( size)
800814 }
801815}
802816
803817#[ derive( Debug , PartialEq ) ]
804818pub struct OsIpcSender {
805- // The client hande itself
806819 handle : WinHandle ,
807820 // Make sure this is `!Sync`, to match `mpsc::Sender`; and to discourage sharing references.
808821 //
@@ -822,8 +835,12 @@ impl Clone for OsIpcSender {
822835 }
823836}
824837
825- // Write_msg, unlike write_buf, requires that bytes be sent
826- // in one operation.
838+ /// Atomic write to a handle.
839+ ///
840+ /// Fails if the data can't be written in a single system call.
841+ /// This is important, since otherwise concurrent sending
842+ /// could result in parts of different messages getting intermixed,
843+ /// and we would not be able to extract the individual messages.
827844fn write_msg ( handle : HANDLE , bytes : & [ u8 ] ) -> Result < ( ) , WinError > {
828845 if bytes. len ( ) == 0 {
829846 return Ok ( ( ) ) ;
@@ -849,6 +866,10 @@ fn write_msg(handle: HANDLE, bytes: &[u8]) -> Result<(),WinError> {
849866 Ok ( ( ) )
850867}
851868
869+ /// Non-atomic write to a handle.
870+ ///
871+ /// Can be used for writes to an exclusive pipe,
872+ /// where the send being split up into several calls poses no danger.
852873fn write_buf ( handle : HANDLE , bytes : & [ u8 ] ) -> Result < ( ) , WinError > {
853874 let total = bytes. len ( ) ;
854875 if total == 0 {
@@ -894,7 +915,7 @@ impl OsIpcSender {
894915 }
895916 }
896917
897- // Connect to a pipe server
918+ /// Connect to a pipe server.
898919 fn connect_named ( pipe_name : & CString ) -> Result < OsIpcSender , WinError > {
899920 unsafe {
900921 let handle =
@@ -953,8 +974,7 @@ impl OsIpcSender {
953974 data_len >= bytes_left_for_data
954975 }
955976
956- // An internal-use-only send method that sends just raw data, with
957- // no header.
977+ /// An internal-use-only send method that sends just raw data, with no header.
958978 fn send_raw ( & self , data : & [ u8 ] ) -> Result < ( ) , WinError > {
959979 win32_trace ! ( "[c {:?}] writing {} bytes raw to (pid {}->{})" , * self . handle, data. len( ) , * CURRENT_PROCESS_ID ,
960980 try!( self . get_pipe_server_process_id( ) ) ) ;
@@ -1064,13 +1084,13 @@ pub enum OsIpcSelectionResult {
10641084}
10651085
10661086pub struct OsIpcReceiverSet {
1067- // Our incrementor, for unique handle IDs
1087+ /// Our incrementor, for unique handle IDs.
10681088 incrementor : Incrementor ,
10691089
1070- // the IOCP that we select on
1090+ /// The IOCP that we select on.
10711091 iocp : WinHandle ,
10721092
1073- // The set of receivers, stored as MessageReaders
1093+ /// The set of receivers, stored as MessageReaders.
10741094 readers : Vec < MessageReader > ,
10751095}
10761096
0 commit comments