From 6a246f5c6d51db1a91f4419871051f81d4b552d9 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Thu, 5 Nov 2020 16:21:49 +0100 Subject: [PATCH] aco/tests: Fix deadlock for too large test lists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The write() to the communication pipe shared with check_output.py would block for large test output streams since the pipe's consumer wouldn't be launched until the write already completed. Reviewed-by: Daniel Schürmann Part-of: --- src/amd/compiler/tests/main.cpp | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/amd/compiler/tests/main.cpp b/src/amd/compiler/tests/main.cpp index cb646e2dd30..b1980217ff2 100644 --- a/src/amd/compiler/tests/main.cpp +++ b/src/amd/compiler/tests/main.cpp @@ -173,14 +173,28 @@ int check_output(char **argv) int stdin_pipe[2]; pipe(stdin_pipe); - write(stdin_pipe[1], checker_stdin_data, checker_stdin_size); - close(stdin_pipe[1]); - dup2(stdin_pipe[0], STDIN_FILENO); + pid_t child_pid = fork(); + if (child_pid == -1) { + fprintf(stderr, "%s: fork() failed: %s\n", argv[0], strerror(errno)); + return 99; + } else if (child_pid != 0) { + /* Evaluate test output externally using Python */ + dup2(stdin_pipe[0], STDIN_FILENO); + close(stdin_pipe[0]); + close(stdin_pipe[1]); - execlp(ACO_TEST_PYTHON_BIN, ACO_TEST_PYTHON_BIN, ACO_TEST_SOURCE_DIR "/check_output.py", NULL); - - fprintf(stderr, "%s: execl() failed: %s\n", argv[0], strerror(errno)); - return 99; + execlp(ACO_TEST_PYTHON_BIN, ACO_TEST_PYTHON_BIN, ACO_TEST_SOURCE_DIR "/check_output.py", NULL); + fprintf(stderr, "%s: execlp() failed: %s\n", argv[0], strerror(errno)); + return 99; + } else { + /* Feed input data to the Python process. Writing large streams to + * stdin will block eventually, so this is done in a forked process + * to let the test checker process chunks of data as they arrive */ + write(stdin_pipe[1], checker_stdin_data, checker_stdin_size); + close(stdin_pipe[0]); + close(stdin_pipe[1]); + exit(0); + } } bool match_test(std::string name, std::string pattern)