/// Spawn a canister sandbox process and yield RPC interface object to
/// communicate with it. When the socket is closed by the other side,
/// we check if the safe_shutdown flag was set. If not this function
/// will initiate an exit (or a panic during testing).
///
/// # Panics & exit
///
/// This function panics upon socket close if safe_shutdown flag is
/// unset. The caller of the function is expected to set/unset the flag.
Spawn a canister sandbox process and yield RPC interface object to
communicate with it. When the socket is closed by the other side,
we check if the safe_shutdown flag was set. If not this function
will initiate an exit (or a panic during testing).
Spawn a canister sandbox process and yield RPC interface object to communicate with it . When the socket is closed by the other side we check if the safe_shutdown flag was set . If not this function will initiate an exit ( or a panic during testing ) .
pub fn spawn_canister_sandbox_process_with_factory(
    exec_path: &str,
    argv: &[String],
    controller_service: Arc<dyn rpc::DemuxServer<ctlsvc::Request, ctlsvc::Reply> + Send + Sync>,
    safe_shutdown: Arc<AtomicBool>,
) -> std::io::Result<(Arc<dyn SandboxService>, Pid, std::thread::JoinHandle<()>)> {
    let SocketedProcess {
        pid,
        control_stream: socket,
    } = spawn_socketed_process(exec_path, argv)?;
    let socket = Arc::new(socket);
    // Set up outgoing channel.
    let out = transport::UnixStreamMuxWriter::<protocol::transport::ControllerToSandbox>::new(
        Arc::clone(&socket),
    );
    // Construct RPC client to sandbox process.
    let reply_handler = Arc::new(rpc::ReplyManager::<protocol::sbxsvc::Reply>::new());
    let svc = Arc::new(SandboxClientStub::new(rpc::Channel::new(
        out.make_sink::<protocol::sbxsvc::Request>(),
        reply_handler.clone(),
    )));
    // Set up thread to handle incoming channel -- replies are routed
    // to reply buffer, requests to the RPC request handler given.
    let thread_handle = std::thread::spawn(move || {
        let demux = transport::Demux::<_, _, protocol::transport::SandboxToController>::new(
            Arc::new(rpc::ServerStub::new(
                controller_service,
                out.make_sink::<protocol::ctlsvc::Reply>(),
            )),
            reply_handler,
        );
        transport::socket_read_messages::<_, _>(
            move |message| {
                demux.handle(message);
            },
            socket,
        );
        // If we the connection drops, but it is not terminated from
        // our end, that implies that the sandbox process died. At
        // that point we need to terminate replica as we have no way
        // to progress execution safely, and we can not restart
        // execution in a deterministic and safe manner that will not
        // corrupt the state.
        if !safe_shutdown.load(Ordering::SeqCst) {
            abort_and_shutdown();
        }
    });
    Ok((svc, Pid::from_raw(pid), thread_handle))
}
pub fn spawn_canister_sandbox_process_with_factory ( exec_path : & str , argv : & [ String ] , controller_service : Arc < dyn rpc :: DemuxServer < ctlsvc :: Request , ctlsvc :: Reply > + Send + Sync > , safe_shutdown : Arc < AtomicBool > , ) -> std :: io :: Result < ( Arc < dyn SandboxService > , Pid , std :: thread :: JoinHandle < ( ) > ) > { let SocketedProcess { pid , control_stream : socket , } = spawn_socketed_process ( exec_path , argv ) ? ; let socket = Arc :: new ( socket ) ; // Set up outgoing channel. let out = transport :: UnixStreamMuxWriter :: < protocol :: transport :: ControllerToSandbox > :: new ( Arc :: clone ( & socket ) , ) ; // Construct RPC client to sandbox process. let reply_handler = Arc :: new ( rpc :: ReplyManager :: < protocol :: sbxsvc :: Reply > :: new ( ) ) ; let svc = Arc :: new ( SandboxClientStub :: new ( rpc :: Channel :: new ( out . make_sink :: < protocol :: sbxsvc :: Request > ( ) , reply_handler . clone ( ) , ) ) ) ; // Set up thread to handle incoming channel -- replies are routed // to reply buffer, requests to the RPC request handler given. let thread_handle = std :: thread :: spawn ( move | | { let demux = transport :: Demux :: < _ , _ , protocol :: transport :: SandboxToController > :: new ( Arc :: new ( rpc :: ServerStub :: new ( controller_service , out . make_sink :: < protocol :: ctlsvc :: Reply > ( ) , ) ) , reply_handler , ) ; transport :: socket_read_messages :: < _ , _ > ( move | message | { demux . handle ( message ) ; } , socket , ) ; // If we the connection drops, but it is not terminated from // our end, that implies that the sandbox process died. At // that point we need to terminate replica as we have no way // to progress execution safely, and we can not restart // execution in a deterministic and safe manner that will not // corrupt the state. if ! safe_shutdown . load ( Ordering :: SeqCst ) { abort_and_shutdown ( ) ; } } ) ; Ok ( ( svc , Pid :: from_raw ( pid ) , thread_handle ) ) }
Spawn a canister sandbox process and yield RPC interface object to
communicate with it.
Spawn a canister sandbox process and yield RPC interface object to communicate with it .
exec_path
&str
argv
&[String]
controller_service
Arc<dyn rpc::DemuxServer<ctlsvc::Request, ctlsvc::Reply> + Send + Sync>
safe_shutdown
Arc<AtomicBool>
panics & exit
This function panics upon socket close if safe_shutdown flag is
unset. The caller of the function is expected to set/unset the flag.
This function panics upon socket close if safe_shutdown flag is unset . The caller of the function is expected to set / unset the flag .