diff --git a/src/ipc.rs b/src/ipc.rs index 8411eb61..3647fc54 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -359,6 +359,7 @@ where /// /// [IpcSender]: struct.IpcSender.html /// [IpcOneShotServer]: struct.IpcOneShotServer.html + #[deprecated(since="0.20.0", note="please use `new_with_connector` instead")] pub fn connect(name: String) -> Result, io::Error> { Ok(IpcSender { os_sender: OsIpcSender::connect(name)?, @@ -875,6 +876,7 @@ impl IpcOneShotServer where T: for<'de> Deserialize<'de> + Serialize, { + #[deprecated(since="0.20.0", note="please use `new_with_connector` instead")] pub fn new() -> Result<(IpcOneShotServer, String), io::Error> { let (os_server, name) = OsIpcOneShotServer::new()?; Ok(( @@ -886,6 +888,21 @@ where )) } + pub fn new_with_connector() -> Result<(IpcOneShotServer, IpcConnector), io::Error> { + let (os_server, name) = OsIpcOneShotServer::new()?; + Ok(( + IpcOneShotServer { + os_server, + phantom: PhantomData, + }, + IpcConnector { + name, + phantom: PhantomData, + }, + )) + + } + pub fn accept(self) -> Result<(IpcReceiver, T), bincode::Error> { let (os_receiver, ipc_message) = self.os_server.accept()?; Ok(( @@ -898,6 +915,25 @@ where } } +/// A means of connecting to an [IpcOneShotServer]. +/// [IpcOneShotServer]: struct.IpcOneShotServer.html +pub struct IpcConnector { + name: String, + phantom: PhantomData, +} + +impl IpcConnector +where + T: for<'de> Deserialize<'de> + Serialize, +{ + pub fn connect(self) -> Result, io::Error> { + Ok(IpcSender { + os_sender: OsIpcSender::connect(self.name)?, + phantom: PhantomData, + }) + } +} + /// Receiving end of a channel that does not used serialized messages. #[derive(Debug)] pub struct IpcBytesReceiver { diff --git a/src/test.rs b/src/test.rs index 83d01bec..20f086f5 100644 --- a/src/test.rs +++ b/src/test.rs @@ -265,6 +265,34 @@ fn cross_process_embedded_senders_fork() { assert_eq!(received_person, person); } +#[cfg(not(any( + feature = "force-inprocess", + target_os = "windows", + target_os = "android", + target_os = "ios" +)))] +#[test] +fn cross_process_embedded_senders_fork_with_connector() { + let person = ("Patrick Walton".to_owned(), 29); + let (server0, server0_connector) = IpcOneShotServer::new_with_connector().unwrap(); + let (server2, server2_connector) = IpcOneShotServer::new_with_connector().unwrap(); + let child_pid = unsafe { + fork(|| { + let (tx1, rx1): (IpcSender, IpcReceiver) = ipc::channel().unwrap(); + let tx0 = server0_connector.connect().unwrap(); + tx0.send(tx1).unwrap(); + rx1.recv().unwrap(); + let tx2: IpcSender = server2_connector.connect().unwrap(); + tx2.send(person.clone()).unwrap(); + }) + }; + let (_, tx1): (_, IpcSender) = server0.accept().unwrap(); + tx1.send(person.clone()).unwrap(); + let (_, received_person): (_, Person) = server2.accept().unwrap(); + child_pid.wait(); + assert_eq!(received_person, person); +} + #[test] fn router_simple_global() { // Note: All ROUTER operation need to run in a single test,