mpstthree/transport/tcp/
fork.rs

1//! This module contains the functions for
2//! forking binary sessions and
3//! the related TcpStream.
4//!
5//! *This module is available only if MultiCrusty is built with
6//! the `"transport"` feature or the `"transport_tcp"` feature.*
7
8use crate::binary::struct_trait::session::Session;
9use std::error::Error;
10use std::marker;
11use std::net::TcpStream;
12use std::panic;
13use std::thread::{Builder, JoinHandle};
14
15type TcpFork<T> = Result<(JoinHandle<()>, T, TcpStream), Box<dyn Error>>;
16
17/// Creates a child process, and a session with two dual
18/// endpoints of type `S` and `S::Dual`. The first endpoint
19/// is given to the child process. Returns the
20/// second endpoint.
21///
22/// *This function is available only if MultiCrusty is built with
23/// the `"transport"` feature or the `"transport_tcp"` feature.*
24#[cfg_attr(
25    doc_cfg,
26    doc(cfg(any(feature = "transport", feature = "transport_tcp")))
27)]
28pub fn fork_tcp<S, P>(p: P, address: &str) -> TcpFork<S::Dual>
29where
30    S: Session + 'static,
31    P: FnOnce(S, TcpStream) -> Result<(), Box<dyn Error>> + marker::Send + 'static,
32{
33    let stream = TcpStream::connect(address)?;
34    let copy_stream = stream.try_clone()?;
35    let (there, here) = Session::new();
36    let other_thread = Builder::new()
37        .name(String::from(address))
38        .stack_size(64 * 1024 * 1024)
39        .spawn(move || {
40            panic::set_hook(Box::new(|_info| {
41                // do nothing
42            }));
43            match p(there, copy_stream) {
44                Ok(()) => (),
45                Err(e) => panic!("{}", e.to_string()),
46            }
47        })?;
48    Ok((other_thread, here, stream))
49}