99
1010use platform:: { self , OsIpcChannel , OsIpcReceiverSet } ;
1111use platform:: { OsIpcSharedMemory } ;
12+ use std:: path:: PathBuf ;
13+ use std:: process:: Command ;
14+ use std:: process:: Stdio ;
1215use std:: sync:: Arc ;
1316use std:: time:: { Duration , Instant } ;
1417use std:: thread;
18+ use std:: env;
1519
16- #[ cfg( not( any( feature = "force-inprocess" , target_os = "windows" , target_os = " android") ) ) ]
20+ #[ cfg( not( any( feature = "force-inprocess" , target_os = "android" ) ) ) ]
1721use libc;
1822use platform:: { OsIpcSender , OsIpcOneShotServer } ;
1923#[ cfg( not( any( feature = "force-inprocess" , target_os = "windows" , target_os = "android" ) ) ) ]
@@ -176,7 +180,8 @@ fn big_data_with_sender_transfer() {
176180}
177181
178182#[ cfg( all( not( feature = "force-inprocess" ) , any( target_os = "linux" ,
179- target_os = "freebsd" ) ) ) ]
183+ target_os = "freebsd" ,
184+ target_os = "windows" ) ) ) ]
180185fn with_n_fds ( n : usize , size : usize ) {
181186 let ( sender_fds, receivers) : ( Vec < _ > , Vec < _ > ) = ( 0 ..n) . map ( |_| platform:: channel ( ) . unwrap ( ) )
182187 . map ( |( tx, rx) | ( OsIpcChannel :: Sender ( tx) , rx) )
@@ -209,7 +214,8 @@ fn with_n_fds(n: usize, size: usize) {
209214
210215// These tests only apply to platforms that need fragmentation.
211216#[ cfg( all( not( feature = "force-inprocess" ) , any( target_os = "linux" ,
212- target_os = "freebsd" ) ) ) ]
217+ target_os = "freebsd" ,
218+ target_os = "windows" ) ) ) ]
213219mod fragment_tests {
214220 use platform;
215221 use super :: with_n_fds;
@@ -434,9 +440,57 @@ fn server_connect_first() {
434440 ( data, vec![ ] , vec![ ] ) ) ;
435441}
436442
443+ #[ cfg( not( any( feature = "force-inprocess" , target_os = "android" ) ) ) ]
444+ #[ test]
445+ #[ ignore]
446+ fn cross_process_server ( )
447+ {
448+ let mut channel_name: Option < String > = None ;
449+ let data: & [ u8 ] = b"1234567" ;
450+
451+ for arg in env:: args ( ) {
452+ if arg. starts_with ( "channel_name:" ) {
453+ let ( _, name) = arg. split_at ( "channel_name:" . len ( ) ) ;
454+ channel_name = Some ( String :: from ( name) ) ;
455+ }
456+ }
457+
458+ if channel_name. is_none ( ) {
459+ return ;
460+ }
461+
462+ let tx = OsIpcSender :: connect ( channel_name. unwrap ( ) ) . unwrap ( ) ;
463+ tx. send ( data, vec ! [ ] , vec ! [ ] ) . unwrap ( ) ;
464+ unsafe { libc:: exit ( 0 ) ; }
465+ }
466+
467+ #[ cfg( not( any( feature = "force-inprocess" , target_os = "android" ) ) ) ]
468+ #[ test]
469+ fn cross_process_spawn ( ) {
470+ let ( server, name) = OsIpcOneShotServer :: new ( ) . unwrap ( ) ;
471+ let data: & [ u8 ] = b"1234567" ;
472+
473+ let mut process = Command :: new ( env:: current_exe ( ) . unwrap ( ) ) ;
474+ let mut child_pid = process. arg ( "--ignored" )
475+ . arg ( "cross_process_server" )
476+ . arg ( format ! ( "channel_name:{}" , name) )
477+ . stdout ( Stdio :: null ( ) )
478+ . stdin ( Stdio :: null ( ) )
479+ . stderr ( Stdio :: null ( ) )
480+ . spawn ( )
481+ . expect ( "failed to execute server process" ) ;
482+
483+ let ( _, mut received_data, received_channels, received_shared_memory_regions) =
484+ server. accept ( ) . unwrap ( ) ;
485+ child_pid. wait ( ) . expect ( "failed to wait on child" ) ;
486+ received_data. truncate ( 7 ) ;
487+ assert_eq ! ( ( & received_data[ ..] , received_channels, received_shared_memory_regions) ,
488+ ( data, vec![ ] , vec![ ] ) ) ;
489+ }
490+
437491#[ cfg( not( any( feature = "force-inprocess" , target_os = "windows" , target_os = "android" ) ) ) ]
438492#[ test]
439- fn cross_process ( ) {
493+ fn cross_process_fork ( ) {
440494 let ( server, name) = OsIpcOneShotServer :: new ( ) . unwrap ( ) ;
441495 let data: & [ u8 ] = b"1234567" ;
442496
@@ -454,9 +508,68 @@ fn cross_process() {
454508 ( data, vec![ ] , vec![ ] ) ) ;
455509}
456510
511+ #[ cfg( not( any( feature = "force-inprocess" , target_os = "android" ) ) ) ]
512+ #[ test]
513+ #[ ignore]
514+ fn cross_process_sender_transfer_server ( )
515+ {
516+ let mut channel_name: Option < String > = None ;
517+ let data: & [ u8 ] = b"1234567" ;
518+
519+ for arg in env:: args ( ) {
520+ if arg. starts_with ( "channel_name:" ) {
521+ let ( _, name) = arg. split_at ( "channel_name:" . len ( ) ) ;
522+ channel_name = Some ( String :: from ( name) ) ;
523+ }
524+ }
525+
526+ if channel_name. is_none ( ) {
527+ return ;
528+ }
529+
530+ let super_tx = OsIpcSender :: connect ( channel_name. unwrap ( ) ) . unwrap ( ) ;
531+ let ( sub_tx, sub_rx) = platform:: channel ( ) . unwrap ( ) ;
532+ let data: & [ u8 ] = b"foo" ;
533+ super_tx. send ( data, vec ! [ OsIpcChannel :: Sender ( sub_tx) ] , vec ! [ ] ) . unwrap ( ) ;
534+ sub_rx. recv ( ) . unwrap ( ) ;
535+ let data: & [ u8 ] = b"bar" ;
536+ super_tx. send ( data, vec ! [ ] , vec ! [ ] ) . unwrap ( ) ;
537+ unsafe { libc:: exit ( 0 ) ; }
538+ }
539+
540+ #[ cfg( not( any( feature = "force-inprocess" , target_os = "android" ) ) ) ]
541+ #[ test]
542+ fn cross_process_sender_transfer_spawn ( ) {
543+ let ( server, name) = OsIpcOneShotServer :: new ( ) . unwrap ( ) ;
544+
545+ let mut process = Command :: new ( env:: current_exe ( ) . unwrap ( ) ) ;
546+ let mut child_pid = process. arg ( "--ignored" )
547+ . arg ( "cross_process_sender_transfer_server" )
548+ . arg ( format ! ( "channel_name:{}" , name) )
549+ . stdout ( Stdio :: null ( ) )
550+ . stdin ( Stdio :: null ( ) )
551+ . stderr ( Stdio :: null ( ) )
552+ . spawn ( )
553+ . expect ( "failed to execute server process" ) ;
554+
555+ let ( super_rx, _, mut received_channels, _) = server. accept ( ) . unwrap ( ) ;
556+ assert_eq ! ( received_channels. len( ) , 1 ) ;
557+ let sub_tx = received_channels. pop ( ) . unwrap ( ) . to_sender ( ) ;
558+ let data: & [ u8 ] = b"baz" ;
559+ sub_tx. send ( data, vec ! [ ] , vec ! [ ] ) . unwrap ( ) ;
560+
561+ let data: & [ u8 ] = b"bar" ;
562+ let ( mut received_data, received_channels, received_shared_memory_regions) =
563+ super_rx. recv ( ) . unwrap ( ) ;
564+ child_pid. wait ( ) . expect ( "failed to wait on child" ) ;
565+ received_data. truncate ( 3 ) ;
566+ assert_eq ! ( ( & received_data[ ..] , received_channels, received_shared_memory_regions) ,
567+ ( data, vec![ ] , vec![ ] ) ) ;
568+ }
569+
457570#[ cfg( not( any( feature = "force-inprocess" , target_os = "windows" , target_os = "android" ) ) ) ]
458571#[ test]
459- fn cross_process_sender_transfer ( ) {
572+ fn cross_process_sender_transfer_fork ( ) {
460573 let ( server, name) = OsIpcOneShotServer :: new ( ) . unwrap ( ) ;
461574
462575 let child_pid = unsafe { fork ( || {
0 commit comments