diff options
author | Michael Widenius <monty@askmonty.org> | 2010-04-08 14:56:57 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2010-04-08 14:56:57 +0300 |
commit | 4a4627104d93452d15fefbcc8cce8ab201b815fb (patch) | |
tree | 07f248cc386047443e646050a3d45b5b1e84e1fe | |
parent | 04ff96f7891cf4a714a3f60a4ec15b5ead7a3f31 (diff) | |
download | mariadb-git-4a4627104d93452d15fefbcc8cce8ab201b815fb.tar.gz |
Fixed race condition in safe_process.cc which may have caused some mysqltests to be reported as failed even if they succeded.
mysql-test/lib/My/SafeProcess/safe_process.cc:
Fixed race condition when getting a signal while calling waitpid()
Don't send kill on killed processes
Return different exit codes depending on how we die.
-rw-r--r-- | mysql-test/lib/My/SafeProcess/safe_process.cc | 47 |
1 files changed, 14 insertions, 33 deletions
diff --git a/mysql-test/lib/My/SafeProcess/safe_process.cc b/mysql-test/lib/My/SafeProcess/safe_process.cc index f9da9560693..71942565f8b 100644 --- a/mysql-test/lib/My/SafeProcess/safe_process.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process.cc @@ -85,17 +85,18 @@ static void die(const char* fmt, ...) va_end(args); if (int last_err= errno) fprintf(stderr, "error: %d, %s\n", last_err, strerror(last_err)); - exit(1); + exit(6); } -static void kill_child(void) +static void kill_child(bool was_killed) { int status= 0; message("Killing child: %d", child_pid); // Terminate whole process group - kill(-child_pid, SIGKILL); + if (! was_killed) + kill(-child_pid, SIGKILL); pid_t ret_pid= waitpid(child_pid, &status, 0); if (ret_pid == child_pid) @@ -115,7 +116,7 @@ static void kill_child(void) exit(exit_code); } - exit(1); + exit(5); } @@ -135,7 +136,7 @@ extern "C" void handle_signal(int sig) terminated= 1; if (child_pid > 0) - kill_child(); + kill_child(sig == SIGCHLD); // Ignore further signals signal(SIGTERM, SIG_IGN); @@ -240,8 +241,8 @@ int main(int argc, char* const argv[] ) // Close write end close(pfd[1]); - if (execvp(child_argv[0], child_argv) < 0) - die("Failed to exec child"); + execvp(child_argv[0], child_argv); + die("Failed to exec child"); } close(pfd[1]); // Close unused write end @@ -257,39 +258,19 @@ int main(int argc, char* const argv[] ) /* Monitor loop */ message("Started child %d, terminated: %d", child_pid, terminated); - while(!terminated) + while (!terminated) { // Check if parent is still alive - if (kill(parent_pid, 0) != 0){ + if (kill(parent_pid, 0) != 0) + { message("Parent is not alive anymore"); break; } - - // Check if child has exited, normally this will be - // detected immediately with SIGCHLD handler - int status= 0; - pid_t ret_pid= waitpid(child_pid, &status, WNOHANG); - if (ret_pid == child_pid) - { - int ret_code= 2; - if (WIFEXITED(status)) - { - // Process has exited, collect return status - ret_code= WEXITSTATUS(status); - message("Child exit: %d", ret_code); - // Exit with exit status of the child - exit(ret_code); - } - - if (WIFSIGNALED(status)) - message("Child killed by signal: %d", WTERMSIG(status)); - - exit(ret_code); - } + /* Wait for parent or child to die */ sleep(1); } - kill_child(); + kill_child(0); - return 1; + return 4; } |