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

sleeper: handle out of order cont/term signals #37

Closed
wants to merge 1 commit into from

Conversation

snakpak
Copy link
Contributor

@snakpak snakpak commented Aug 21, 2018

Another solution to issue #25, the so-called "missing CONT" failure in svc and supervise-stop tests. The problem is that supervise sends a TERM then CONT signal pair in response to 'svc -d', but sleeper expects a CONT followed by a TERM.

Normally the kernel will propagate the two in descending order (CONT/TERM) as sleeper expects, but since there's no way to generate both at the same time, it's possible the TERM could be delivered before the CONT is even sent.

This patch handles either case in sleeper by using a look-behind whenever either signal is seen. It also tightens up the signal handler by moving most of the logic back to the main loop.

@bruceg
Copy link
Owner

bruceg commented Sep 21, 2018

This is a pretty ugly approach, for a number of reasons:

  1. It explodes the logic required in main to handle the output.
  2. It hard codes CONT and TERM as special signals.
  3. The macros separate the logic of state_## from their usage, which becomes just extra lines of code (single use macro which does more to hide what is being compared than anything).
  4. That sig_queue could trivially be turned into a circular buffer instead of needing the boundary condition in catch_sig.
  5. The expanded macros compare the (new_sig == SIGCONT) etc repeatedly instead of memorizing them (int new_cont = new_sig == SIGCONT; etc).

What about something like treating sig_queue as an array of flags, and scanning it each time a signal is received so that signals are always displayed in the same order? I don't think I have ever seen this failure, so it's hard for me to test

@snakpak
Copy link
Contributor Author

snakpak commented Sep 22, 2018

Here's a different version (3dd15aa), based on a self pipe. I like it a little more since it eliminates sig_queue entirely, and thus the problems a circular buffer would create. Not to mention the already existing race in main between the pointer comparison and the sleep call.

The new version removes the macros and the redundant comparisons, as you mentioned, but not much I can do about the code explosion -- unless moving that loop out of main is what you're getting at.

But as for CONT and TERM being treated specially, in this particular case they are special, mainly because svc -d sends both. And since there's no way to know what order they'll arrive in, if sleeper sees either one it can't exit immediately as usual. It has to also print the next signal or risk breaking the pair.

I do like the array of flags idea though (or maybe counters?), but seems like that would only make sense if sleeper were persistent and needed to sort more than just the two we're interested in.

@snakpak
Copy link
Contributor Author

snakpak commented Sep 28, 2018

Continued in PR#53.

@snakpak snakpak closed this Sep 28, 2018
@snakpak snakpak deleted the missing-sigcont branch September 28, 2018 08:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants