@@ -324,25 +324,19 @@ pub fn start_container(
324324 docker_host : & str ,
325325 logger : & Logger ,
326326) -> ToolsetResult < ( ) > {
327+ let cid = container_id. to_string ( ) ;
328+ let host = docker_host. to_string ( ) ;
329+ let use_unix_socket = docker_config. use_unix_socket ;
330+ let logger = logger. clone ( ) ;
331+ thread:: spawn ( move || {
332+ attach_to_container ( & cid, & host, use_unix_socket, Application :: new ( & logger) ) . unwrap ( ) ;
333+ } ) ;
327334 dockurl:: container:: start_container (
328335 container_id,
329336 docker_host,
330337 docker_config. use_unix_socket ,
331338 Simple :: new ( ) ,
332339 ) ?;
333- let container_id = container_id. to_string ( ) ;
334- let docker_host = docker_config. client_docker_host . clone ( ) ;
335- let use_unix_socket = docker_config. use_unix_socket ;
336- let logger = logger. clone ( ) ;
337- thread:: spawn ( move || {
338- attach_to_container (
339- & container_id,
340- & docker_host,
341- use_unix_socket,
342- Application :: new ( & logger) ,
343- )
344- . unwrap ( ) ;
345- } ) ;
346340 Ok ( ( ) )
347341}
348342
@@ -448,29 +442,40 @@ pub fn start_verification_container(
448442 errors : vec ! [ ] ,
449443 } ;
450444 let verification = Arc :: new ( Mutex :: new ( to_ret. clone ( ) ) ) ;
451- dockurl:: container:: start_container (
452- & container_id,
453- & docker_config. client_docker_host ,
454- docker_config. use_unix_socket ,
455- Simple :: new ( ) ,
456- ) ?;
457445
458446 let verifier_container_id = container_id. to_string ( ) ;
459447 let config = docker_config. clone ( ) ;
460- let client_docker_host = config. client_docker_host . clone ( ) ;
448+ let client_docker_host = config. client_docker_host ;
461449 let use_unix_socket = docker_config. use_unix_socket ;
462450 let verifier_logger = logger. clone ( ) ;
463- let mut inner_verification = Arc :: clone ( & verification) ;
451+ let inner_verification = Arc :: clone ( & verification) ;
452+ // This function is extremely complicated and seemingly in the wrong order, but it is very
453+ // convoluted and intended. We attach to the container *before* it is started in a new thread,
454+ // and, using an Arc, communicate stderr/stdout and messages from the container (when it runs)
455+ // to the main thread.
456+ // `attach_to_container` blocks and therefore must be in a separate thread.
457+ // If we did `attach` *after* `start_container`, then there is an **INTENDED** implementation
458+ // in Docker to **NOT** close the connection, so this would block indefinitely.
459+ // It is safe to trust this implementation in the thread because we `attach` **BEFORE** the
460+ // container is started, and therefore it *will* exit after we are `attached` which will close
461+ // the connection.
464462 thread:: spawn ( move || {
465463 dockurl:: container:: attach_to_container (
466464 & verifier_container_id,
467465 & client_docker_host,
468466 use_unix_socket,
469- Verifier :: new ( Arc :: clone ( & mut inner_verification) , & verifier_logger) ,
467+ Verifier :: new ( Arc :: clone ( & inner_verification) , & verifier_logger) ,
470468 )
471469 . unwrap ( ) ;
472470 } ) ;
473471
472+ dockurl:: container:: start_container (
473+ & container_id,
474+ & docker_config. client_docker_host ,
475+ docker_config. use_unix_socket ,
476+ Simple :: new ( ) ,
477+ ) ?;
478+
474479 wait_for_container_to_exit (
475480 & container_id,
476481 & docker_config. client_docker_host ,
0 commit comments