@@ -686,13 +686,19 @@ let capture_stdout_logs arg =
686686 (* Ensure cleanup even if arg() fails *)
687687 Stdlib. flush Stdlib. stdout; (* Flush to pipe_write_fd *)
688688 Unix. close pipe_write_fd; (* Signal EOF to reader domain *)
689- (try Domain. join reader_domain
690- with e ->
691- Stdio. eprintf " Exception while joining reader domain (arg failed): %s \\ n%! "
692- ( Exn. to_string e));
693-
689+ (* Restore stdout before waiting for the reader domain so that the
690+ write end of the pipe is effectively closed (both the explicit
691+ [pipe_write_fd] descriptor above _and_ the descriptor 1 obtained
692+ via [dup2] earlier). Otherwise the reader domain would never see
693+ an EOF and [Domain.join] would block indefinitely. *)
694694 Unix. dup2 original_stdout_fd Unix. stdout; (* Restore stdout *)
695695 Unix. close original_stdout_fd;
696+
697+ (* Now that all write descriptors for the pipe are closed, we can
698+ wait for the reader domain to finish. *)
699+ (try Domain. join reader_domain
700+ with e ->
701+ Stdio. eprintf " Exception while joining reader domain (arg failed): %s\\ n%!" (Exn. to_string e));
696702 advance_captured_logs := old_advance_captured_logs_val;
697703
698704 if not (Atomic. get reader_domain_failed) then (
@@ -712,15 +718,17 @@ let capture_stdout_logs arg =
712718 Stdlib. flush Stdlib. stdout; (* Flush to pipe_write_fd *)
713719 Unix. close pipe_write_fd; (* Signal EOF to reader domain *)
714720
721+ (* Restore stdout before waiting for the reader domain so that the
722+ write end of the pipe is effectively closed and the reader can finish
723+ properly. *)
724+ Unix. dup2 original_stdout_fd Unix. stdout; (* Restore stdout *)
725+ Unix. close original_stdout_fd;
726+
715727 (try Domain. join reader_domain
716728 with e ->
717- Stdio. eprintf " Exception while joining reader domain (arg succeeded): %s\\ n%!"
718- (Exn. to_string e);
729+ Stdio. eprintf " Exception while joining reader domain (arg succeeded): %s\\ n%!" (Exn. to_string e);
719730 if Atomic. get reader_domain_failed then
720731 Stdlib.Printexc. raise_with_backtrace e (Stdlib.Printexc. get_raw_backtrace () ));
721-
722- Unix. dup2 original_stdout_fd Unix. stdout; (* Restore stdout *)
723- Unix. close original_stdout_fd;
724732 advance_captured_logs := old_advance_captured_logs_val;
725733
726734 if not (Atomic. get reader_domain_failed) then (
0 commit comments