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" ) ) ) ]
@@ -175,7 +179,7 @@ fn big_data_with_sender_transfer() {
175179 thread. join ( ) . unwrap ( ) ;
176180}
177181
178- #[ cfg( all( not( feature = "force-inprocess" ) , target_os = "linux" ) ) ]
182+ #[ cfg( all( not( feature = "force-inprocess" ) , any ( target_os = "linux" , target_os = "windows" ) ) ) ]
179183fn with_n_fds ( n : usize , size : usize ) {
180184 let ( sender_fds, receivers) : ( Vec < _ > , Vec < _ > ) = ( 0 ..n) . map ( |_| platform:: channel ( ) . unwrap ( ) )
181185 . map ( |( tx, rx) | ( OsIpcChannel :: Sender ( tx) , rx) )
@@ -207,7 +211,7 @@ fn with_n_fds(n: usize, size: usize) {
207211}
208212
209213// These tests only apply to platforms that need fragmentation.
210- #[ cfg( all( not( feature = "force-inprocess" ) , target_os = "linux" ) ) ]
214+ #[ cfg( all( not( feature = "force-inprocess" ) , any ( target_os = "linux" , target_os = "windows" ) ) ) ]
211215mod fragment_tests {
212216 use platform;
213217 use super :: with_n_fds;
@@ -432,9 +436,57 @@ fn server_connect_first() {
432436 ( data, vec![ ] , vec![ ] ) ) ;
433437}
434438
439+ #[ cfg( not( any( feature = "force-inprocess" , target_os = "android" ) ) ) ]
440+ #[ test]
441+ #[ ignore]
442+ fn cross_process_server ( )
443+ {
444+ let mut channel_name: Option < String > = None ;
445+ let data: & [ u8 ] = b"1234567" ;
446+
447+ for arg in env:: args ( ) {
448+ if arg. starts_with ( "channel_name:" ) {
449+ let ( _, name) = arg. split_at ( "channel_name:" . len ( ) ) ;
450+ channel_name = Some ( String :: from ( name) ) ;
451+ }
452+ }
453+
454+ if channel_name. is_none ( ) {
455+ return ;
456+ }
457+
458+ let tx = OsIpcSender :: connect ( channel_name. unwrap ( ) ) . unwrap ( ) ;
459+ tx. send ( data, vec ! [ ] , vec ! [ ] ) . unwrap ( ) ;
460+ unsafe { libc:: exit ( 0 ) ; }
461+ }
462+
463+ #[ cfg( not( any( feature = "force-inprocess" , target_os = "android" ) ) ) ]
464+ #[ test]
465+ fn cross_process_spawn ( ) {
466+ let ( server, name) = OsIpcOneShotServer :: new ( ) . unwrap ( ) ;
467+ let data: & [ u8 ] = b"1234567" ;
468+
469+ let mut process = Command :: new ( env:: current_exe ( ) . unwrap ( ) ) ;
470+ let mut child_pid = process. arg ( "--ignored" )
471+ . arg ( "cross_process_server" )
472+ . arg ( format ! ( "channel_name:{}" , name) )
473+ . stdout ( Stdio :: null ( ) )
474+ . stdin ( Stdio :: null ( ) )
475+ . stderr ( Stdio :: null ( ) )
476+ . spawn ( )
477+ . expect ( "failed to execute server process" ) ;
478+
479+ let ( _, mut received_data, received_channels, received_shared_memory_regions) =
480+ server. accept ( ) . unwrap ( ) ;
481+ child_pid. wait ( ) . expect ( "failed to wait on child" ) ;
482+ received_data. truncate ( 7 ) ;
483+ assert_eq ! ( ( & received_data[ ..] , received_channels, received_shared_memory_regions) ,
484+ ( data, vec![ ] , vec![ ] ) ) ;
485+ }
486+
435487#[ cfg( not( any( feature = "force-inprocess" , target_os = "windows" , target_os = "android" ) ) ) ]
436488#[ test]
437- fn cross_process ( ) {
489+ fn cross_process_fork ( ) {
438490 let ( server, name) = OsIpcOneShotServer :: new ( ) . unwrap ( ) ;
439491 let data: & [ u8 ] = b"1234567" ;
440492
@@ -452,9 +504,68 @@ fn cross_process() {
452504 ( data, vec![ ] , vec![ ] ) ) ;
453505}
454506
507+ #[ cfg( not( any( feature = "force-inprocess" , target_os = "android" ) ) ) ]
508+ #[ test]
509+ #[ ignore]
510+ fn cross_process_sender_transfer_server ( )
511+ {
512+ let mut channel_name: Option < String > = None ;
513+ let data: & [ u8 ] = b"1234567" ;
514+
515+ for arg in env:: args ( ) {
516+ if arg. starts_with ( "channel_name:" ) {
517+ let ( _, name) = arg. split_at ( "channel_name:" . len ( ) ) ;
518+ channel_name = Some ( String :: from ( name) ) ;
519+ }
520+ }
521+
522+ if channel_name. is_none ( ) {
523+ return ;
524+ }
525+
526+ let super_tx = OsIpcSender :: connect ( channel_name. unwrap ( ) ) . unwrap ( ) ;
527+ let ( sub_tx, sub_rx) = platform:: channel ( ) . unwrap ( ) ;
528+ let data: & [ u8 ] = b"foo" ;
529+ super_tx. send ( data, vec ! [ OsIpcChannel :: Sender ( sub_tx) ] , vec ! [ ] ) . unwrap ( ) ;
530+ sub_rx. recv ( ) . unwrap ( ) ;
531+ let data: & [ u8 ] = b"bar" ;
532+ super_tx. send ( data, vec ! [ ] , vec ! [ ] ) . unwrap ( ) ;
533+ unsafe { libc:: exit ( 0 ) ; }
534+ }
535+
536+ #[ cfg( not( any( feature = "force-inprocess" , target_os = "android" ) ) ) ]
537+ #[ test]
538+ fn cross_process_sender_transfer_spawn ( ) {
539+ let ( server, name) = OsIpcOneShotServer :: new ( ) . unwrap ( ) ;
540+
541+ let mut process = Command :: new ( env:: current_exe ( ) . unwrap ( ) ) ;
542+ let mut child_pid = process. arg ( "--ignored" )
543+ . arg ( "cross_process_sender_transfer_server" )
544+ . arg ( format ! ( "channel_name:{}" , name) )
545+ . stdout ( Stdio :: null ( ) )
546+ . stdin ( Stdio :: null ( ) )
547+ . stderr ( Stdio :: null ( ) )
548+ . spawn ( )
549+ . expect ( "failed to execute server process" ) ;
550+
551+ let ( super_rx, _, mut received_channels, _) = server. accept ( ) . unwrap ( ) ;
552+ assert_eq ! ( received_channels. len( ) , 1 ) ;
553+ let sub_tx = received_channels. pop ( ) . unwrap ( ) . to_sender ( ) ;
554+ let data: & [ u8 ] = b"baz" ;
555+ sub_tx. send ( data, vec ! [ ] , vec ! [ ] ) . unwrap ( ) ;
556+
557+ let data: & [ u8 ] = b"bar" ;
558+ let ( mut received_data, received_channels, received_shared_memory_regions) =
559+ super_rx. recv ( ) . unwrap ( ) ;
560+ child_pid. wait ( ) . expect ( "failed to wait on child" ) ;
561+ received_data. truncate ( 3 ) ;
562+ assert_eq ! ( ( & received_data[ ..] , received_channels, received_shared_memory_regions) ,
563+ ( data, vec![ ] , vec![ ] ) ) ;
564+ }
565+
455566#[ cfg( not( any( feature = "force-inprocess" , target_os = "windows" , target_os = "android" ) ) ) ]
456567#[ test]
457- fn cross_process_sender_transfer ( ) {
568+ fn cross_process_sender_transfer_fork ( ) {
458569 let ( server, name) = OsIpcOneShotServer :: new ( ) . unwrap ( ) ;
459570
460571 let child_pid = unsafe { fork ( || {
0 commit comments