summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-09-13 16:43:22 +0200
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-09-13 16:48:08 +0200
commita031a1bf93b828585e7147f06145fc5030814547 (patch)
treede6fc2dc1083d952e8ac9384f65cc6a88937b2e0
parent9298dfabd9658315df34616b1e9a10b3579a92bd (diff)
lib/drmtest: ducttape over fork race
Whatever the reason (and I've thought there isn't one) if we fork and kill right away the child seems to not reliably die. We can work around this little race by forcing the default SIGQUIT handler. This should break anything since we reset our atexit handling anyway, so if the helper needs any atexit handling the special signal helpers will be reinstated. Note that inserting sufficient amounts of printf between the fork and kill makes this unnecessary. While add it also add the retry loop for the waitpid call, in case there's another guy constantly interrupting us. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--lib/drmtest.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/lib/drmtest.c b/lib/drmtest.c
index 1ba8cad4..a3ff0d6f 100644
--- a/lib/drmtest.c
+++ b/lib/drmtest.c
@@ -981,6 +981,7 @@ static void fork_helper_exit_handler(int sig)
bool __igt_fork_helper(struct igt_helper_process *proc)
{
pid_t pid;
+ sighandler_t oldsig;
int id;
assert(!proc->running);
@@ -991,6 +992,13 @@ bool __igt_fork_helper(struct igt_helper_process *proc)
igt_install_exit_handler(fork_helper_exit_handler);
+ /*
+ * XXX: There's a race between fork and the subsequent kill in
+ * igt_stop_signal_helper if we don't ovewrite the SIGQUIT handler. Note
+ * that inserting sufficient amounts of printf or other delays makes
+ * this unnecessary.
+ */
+ oldsig = signal(SIGQUIT, SIG_DFL);
switch (pid = fork()) {
case -1:
igt_assert(0);
@@ -1000,6 +1008,8 @@ bool __igt_fork_helper(struct igt_helper_process *proc)
return true;
default:
+ signal(SIGQUIT, oldsig);
+
proc->running = true;
proc->pid = pid;
proc->id = id;
@@ -1023,7 +1033,9 @@ void igt_stop_helper(struct igt_helper_process *proc)
assert(proc->running);
assert(kill(proc->pid, SIGQUIT) == 0);
- waitpid(proc->pid, &status, 0);
+ while (waitpid(proc->pid, &status, 0) == -1 &&
+ errno == -EINTR)
+ ;
proc->running = false;