aco/tests: Fix deadlock for too large test lists

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 <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7461>
This commit is contained in:
Tony Wasserka 2020-11-05 16:21:49 +01:00 committed by Marge Bot
parent a240341ec9
commit 6a246f5c6d

View file

@ -173,14 +173,28 @@ int check_output(char **argv)
int stdin_pipe[2]; int stdin_pipe[2];
pipe(stdin_pipe); pipe(stdin_pipe);
write(stdin_pipe[1], checker_stdin_data, checker_stdin_size); pid_t child_pid = fork();
close(stdin_pipe[1]); 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); 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); 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));
fprintf(stderr, "%s: execl() failed: %s\n", argv[0], strerror(errno));
return 99; 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) bool match_test(std::string name, std::string pattern)