Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

catch slow sigcont #36

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion rts.tests/supervise-stop.exp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
in stop

--- supervise stops log after main
Caught CONT
Caught TERM
Caught CONT

2 changes: 1 addition & 1 deletion rts.tests/svc.exp
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ Caught QUIT
Caught USR1
Caught USR2
Caught WINCH
Caught CONT
Caught TERM
Caught CONT
56 changes: 51 additions & 5 deletions sleeper.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#include "str.h"
#include <unistd.h>

int flag_cont = 0;
int flag_term = 0;

static void catch_sig(int sig)
{
char buf[7+14+2] = "Caught ";
Expand All @@ -12,11 +15,11 @@ static void catch_sig(int sig)
int i;
switch (sig) {
case SIGALRM: name = "ALRM"; break;
case SIGCONT: name = "CONT"; break;
case SIGCONT: flag_cont = 1; return;
case SIGHUP: name = "HUP"; break;
case SIGINT: name = "INT"; break;
case SIGQUIT: name = "QUIT"; break;
case SIGTERM: name = "TERM"; break;
case SIGTERM: flag_term = 1; return;
case SIGUSR1: name = "USR1"; break;
case SIGUSR2: name = "USR2"; break;
case SIGWINCH: name = "WINCH"; break;
Expand All @@ -27,12 +30,13 @@ static void catch_sig(int sig)
i += 7;
buf[i++] = '\n';
ignored = write(1,buf,i);
if (sig != SIGCONT)
_exit(1);
_exit(1);
}

int main(void)
{
int i, ignored;

sig_catch(SIGALRM,catch_sig);
sig_catch(SIGCONT,catch_sig);
sig_catch(SIGHUP,catch_sig);
Expand All @@ -42,6 +46,48 @@ int main(void)
sig_catch(SIGUSR1,catch_sig);
sig_catch(SIGUSR2,catch_sig);
sig_catch(SIGWINCH,catch_sig);
sleep(9999);

for (i = 0; i < 9999; ++i) {
if (!flag_cont && !flag_term) sleep(1);
/*
* here we have some combination of flag_cont and flag_term.
*
* if neither, nothing happened. continue.
*
* if both, then sig_term was interrupted by sig_cont, so we know
* we've handled svc -d. print both and exit.
*
* if only flag_cont set, we know we're handling svc -c since svc -d
* would've either set both (as above) or only set flag_term (below).
* print the cont message and exit.
*
* if only flag_term set, we might be handling svc -t by itself, or
* maybe svc -d has returned from the sig_term handler before sig_cont
* arrived. in either case, reset flag_term, print the term message,
* and continue.
*
* as a special case, if only flag_cont set, we might be handling
* the second half of svc -d where sig_cont arrived so late we already
* looped around here once and handled the sig_term. print the cont
* message and exit.
*
* one hidden gotcha here is that any test following a sig_term will
* be handled by the same sleeper instance as sig_term itself. don't
* schedule a svc -t test last.
*
* another gotcha is the race condition between the flag test above
* and sleep(). if a cont/term signal arrives at that point, we incur
* additional delay which could muck up the tests. don't test svc -c
* immediately after svc -t, and schedule svc -dx test last.
*/
if (flag_term) {
flag_term = 0;
ignored = write(1, "Caught TERM\n", 12);
}
if (flag_cont) {
ignored = write(1, "Caught CONT\n", 12);
_exit(1);
}
}
return 0;
}