From ba9abf303e1bed196668f103b2a17c48e3df70aa Mon Sep 17 00:00:00 2001 From: David Smith Date: Tue, 13 Oct 2009 08:55:57 -0500 Subject: [PATCH] PR 10575. Improves running target commands. * runtime/staprun/mainloop.c (signal_usr1): Renamed from signal_dontcare. Sets a new variable, usr1_interrupt. (start_cmd): Avoids pause() race condition by switching to blocking SIGUSR1, then waiting on SIGUSR1 with sigsuspend(). --- runtime/staprun/mainloop.c | 61 +++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/runtime/staprun/mainloop.c b/runtime/staprun/mainloop.c index 45b142bc9..513a95695 100644 --- a/runtime/staprun/mainloop.c +++ b/runtime/staprun/mainloop.c @@ -60,12 +60,15 @@ static void chld_proc(int signum) } #if WORKAROUND_BZ467568 -/* Used for pause()-based synchronization. */ -static void signal_dontcare(int signum) +/* When a SIGUSR1 signal arrives, set this variable. */ +volatile sig_atomic_t usr1_interrupt = 0; + +static void signal_usr1(int signum) { (void) signum; + usr1_interrupt = 1; } -#endif +#endif /* WORKAROUND_BZ467568 */ static void setup_main_signals(void) { @@ -115,6 +118,10 @@ void start_cmd(void) { pid_t pid; struct sigaction a; +#if WORKAROUND_BZ467568 + struct sigaction usr1_action, old_action; + sigset_t blockmask, oldmask; +#endif /* WORKAROUND_BZ467568 */ /* if we are execing a target cmd, ignore ^C in stapio */ /* and let the target cmd get it. */ @@ -123,6 +130,21 @@ void start_cmd(void) a.sa_handler = SIG_IGN; sigaction(SIGINT, &a, NULL); +#if WORKAROUND_BZ467568 + /* Set up the mask of signals to temporarily block. */ + sigemptyset (&blockmask); + sigaddset (&blockmask, SIGUSR1); + + /* Establish the SIGUSR1 signal handler. */ + sigfillset (&usr1_action.sa_mask); + usr1_action.sa_flags = 0; + usr1_action.sa_handler = signal_usr1; + sigaction (SIGUSR1, &usr1_action, &old_action); + + /* Block SIGUSR1 */ + sigprocmask(SIG_BLOCK, &blockmask, &oldmask); +#endif /* WORKAROUND_BZ467568 */ + if ((pid = fork()) < 0) { _perr("fork"); exit(1); @@ -175,22 +197,21 @@ void start_cmd(void) dbug(1, "blocking briefly\n"); #if WORKAROUND_BZ467568 { - /* We use SIGUSR1 here, since pause() only returns if a - handled signal was received. */ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sigfillset(&sa.sa_mask); - sa.sa_handler = signal_dontcare; - sigaction(SIGUSR1, &sa, NULL); - pause (); - sa.sa_handler = SIG_DFL; - sigaction(SIGUSR1, &sa, NULL); + /* Wait for the SIGUSR1 */ + while (!usr1_interrupt) + sigsuspend(&oldmask); + + /* Restore the old SIGUSR1 signal handler. */ + sigaction (SIGUSR1, &old_action, NULL); + + /* Restore the original signal mask */ + sigprocmask(SIG_SETMASK, &oldmask, NULL); } -#else +#else /* !WORKAROUND_BZ467568 */ rc = ptrace (PTRACE_TRACEME, 0, 0, 0); if (rc < 0) perror ("ptrace me"); raise (SIGCONT); /* Harmless; just passes control to parent. */ -#endif +#endif /* !WORKAROUND_BZ467568 */ dbug(1, "execing target_cmd %s\n", target_cmd); @@ -217,12 +238,16 @@ void start_cmd(void) us to release it. */ target_pid = pid; #if WORKAROUND_BZ467568 - /* Do nothing else here; see stp_main_loop's handling of a received STP_START. */ -#else + /* Restore the old SIGUSR1 signal handler. */ + sigaction (SIGUSR1, &old_action, NULL); + + /* Restore the original signal mask */ + sigprocmask(SIG_SETMASK, &oldmask, NULL); +#else /* !WORKAROUND_BZ467568 */ int status; waitpid (target_pid, &status, 0); dbug(1, "waited for target_cmd %s pid %d status %x\n", target_cmd, target_pid, (unsigned) status); -#endif +#endif /* !WORKAROUND_BZ467568 */ } } -- 2.43.5