summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/igt_aux.c38
-rw-r--r--lib/igt_aux.h2
-rw-r--r--lib/igt_core.c16
3 files changed, 56 insertions, 0 deletions
diff --git a/lib/igt_aux.c b/lib/igt_aux.c
index fa6594c3..8dde9a12 100644
--- a/lib/igt_aux.c
+++ b/lib/igt_aux.c
@@ -350,6 +350,44 @@ void igt_stop_signal_helper(void)
sig_stat = 0;
}
+/**
+ * igt_suspend_signal_helper:
+ *
+ * Suspends the child process spawned with igt_fork_signal_helper(). This
+ * should be called before a critical section of code that has difficulty to
+ * make progress if interrupted frequently, like the clone() syscall called
+ * from a largish executable. igt_resume_signal_helper() must be called after
+ * the critical section to restart interruptions for the test.
+ */
+void igt_suspend_signal_helper(void)
+{
+ int status;
+
+ if (!signal_helper.running)
+ return;
+
+ kill(signal_helper.pid, SIGSTOP);
+ while (waitpid(signal_helper.pid, &status, WUNTRACED) == -1 &&
+ errno == EINTR)
+ ;
+}
+
+/**
+ * igt_resume_signal_helper:
+ *
+ * Resumes the child process spawned with igt_fork_signal_helper().
+ *
+ * This should be paired with igt_suspend_signal_helper() and called after the
+ * problematic code sensitive to signals.
+ */
+void igt_resume_signal_helper(void)
+{
+ if (!signal_helper.running)
+ return;
+
+ kill(signal_helper.pid, SIGCONT);
+}
+
static struct igt_helper_process shrink_helper;
static void __attribute__((noreturn)) shrink_helper_process(int fd, pid_t pid)
{
diff --git a/lib/igt_aux.h b/lib/igt_aux.h
index 499a1679..688ad1b8 100644
--- a/lib/igt_aux.h
+++ b/lib/igt_aux.h
@@ -55,6 +55,8 @@ extern int num_trash_bos;
/* generally useful helpers */
void igt_fork_signal_helper(void);
void igt_stop_signal_helper(void);
+void igt_suspend_signal_helper(void);
+void igt_resume_signal_helper(void);
void igt_fork_shrink_helper(int fd);
void igt_stop_shrink_helper(void);
diff --git a/lib/igt_core.c b/lib/igt_core.c
index 950ea9b0..538a4472 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -2282,6 +2282,13 @@ int igt_system(const char *command)
if (pipe(errpipe) < 0)
goto err;
+ /*
+ * The clone() system call called from a largish executable has
+ * difficulty to make progress if interrupted too frequently, so
+ * suspend the signal helper for the time of the syscall.
+ */
+ igt_suspend_signal_helper();
+
igt_fork_helper(&process) {
close(outpipe[0]);
close(errpipe[0]);
@@ -2298,6 +2305,8 @@ int igt_system(const char *command)
exit(EXIT_FAILURE);
}
+ igt_resume_signal_helper();
+
close(outpipe[1]);
close(errpipe[1]);
@@ -2340,9 +2349,14 @@ int igt_system_quiet(const char *command)
if (dup2(nullfd, STDERR_FILENO) == -1)
goto err;
+ /* See igt_system() for the reason for suspending the signal helper. */
+ igt_suspend_signal_helper();
+
if ((status = system(command)) == -1)
goto err;
+ igt_resume_signal_helper();
+
/* restore */
if (dup2(stdout_fd_copy, STDOUT_FILENO) == -1)
goto err;
@@ -2355,6 +2369,8 @@ int igt_system_quiet(const char *command)
return WEXITSTATUS(status);
err:
+ igt_resume_signal_helper();
+
close(stderr_fd_copy);
close(stdout_fd_copy);
close(nullfd);