summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-07-11 10:15:19 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-07-11 10:41:28 +0100
commitf47ee31dd5d5a5099ed6f5d4a59a12a2f83c8cae (patch)
tree8e36f42d42e9a50df109f47fe2e99c078edff487 /lib
parent3777d42303cf9d285a5337d71623d52402cb3021 (diff)
Wait for any pid in order to reap failure quicker
When waiting for the forked tests, we can respond quicker to a failure (such as oom) by waiting for any child to exit rather than waiting for each child in order. Then when we see that a test failed, we can kill all other children before aborting. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'lib')
-rw-r--r--lib/igt_core.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/lib/igt_core.c b/lib/igt_core.c
index bdeeb599..26b360f2 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -925,32 +925,52 @@ bool __igt_fork(void)
*/
void igt_waitchildren(void)
{
+ int err = 0;
+ int count;
+
assert(!test_child);
- for (int nc = 0; nc < num_test_children; nc++) {
+ count = 0;
+ while (count < num_test_children) {
int status = -1;
- while (waitpid(test_children[nc], &status, 0) == -1 &&
- errno == EINTR)
- ;
+ pid_t pid;
+ int c;
- if (status != 0) {
+ pid = wait(&status);
+ if (pid == -1)
+ continue;
+
+ for (c = 0; c < num_test_children; c++)
+ if (pid == test_children[c])
+ break;
+ if (c == num_test_children)
+ continue;
+
+ if (err == 0 && status != 0) {
if (WIFEXITED(status)) {
printf("child %i failed with exit status %i\n",
- nc, WEXITSTATUS(status));
- igt_fail(WEXITSTATUS(status));
+ c, WEXITSTATUS(status));
+ err = WEXITSTATUS(status);
} else if (WIFSIGNALED(status)) {
printf("child %i died with signal %i, %s\n",
- nc, WTERMSIG(status),
+ c, WTERMSIG(status),
strsignal(WTERMSIG(status)));
- igt_fail(99);
+ err = 128 + WTERMSIG(status);
} else {
- printf("Unhandled failure in child %i\n", nc);
- abort();
+ printf("Unhandled failure [%d] in child %i\n", status, c);
+ err = 256;
}
+
+ for (c = 0; c < num_test_children; c++)
+ kill(test_children[c], SIGKILL);
}
+
+ count++;
}
num_test_children = 0;
+ if (err)
+ igt_fail(err);
}
/* exit handler code */