mpv
mpv copied to clipboard
terminal_thread: only act on last command in stop_cont_pipe
It is possible for stop_cont_sighandler() to be called more than once before terminal_thread can act on the command. For example, if mpv receives multiple SIGTSTP, it will suspend and when resumed will suspend again immediately. Draining the pipe (which is non-blocking) works around this.
On OpenBSD, SIGTSTP appears to be sent to each thread, which makes it impossible to resume mpv since there will always be another PIPE_STOP byte waiting in the pipe.
Download the artifacts for this pull request:
Make sense. @N-R-K do you have opinion on that?
If you act only on the last command in the pipe then it'll miss earlier (but different) signals if they were sent in quick succession (not sure if it'd happen in practice, maybe from some script).
This also seems racy, consider the following ordering:
- N threads are active and receive the signal
- N-1 threads have written to the pipe
- The reader drains the pipe
- Nth thread writes to the pipe
- Now there's an extra STOP command lingering in the pipe still
On OpenBSD, SIGTSTP appears to be sent to each thread
Is openbsd the only platform that does this? If yes, is there a way to disable this behavior instead?
If you act only on the last command in the pipe then it'll miss earlier (but different) signals if they were sent in quick succession
Nevermind this, the other signals are using a separate pipe (death_pipe).
This also seems racy [...]
Is openbsd the only platform that does this?
These still stand though. And from skimming through this thread and some conversation elsewhere, I'm under the impression that sending signal to each thread rather than each process is the buggy behavior here. posix specifies the latter:
"[...] receipt of the SUSP character shall cause a SIGTSTP signal to be sent to all processes in the foreground process group for which the terminal is the controlling terminal [...]"
Well, a process is just a collection of associated threads. POSIX says "Signals generated for the process shall be delivered to exactly one of those threads within the process which is in a call to a sigwait() function selecting that signal or has not blocked delivery of the signal." From my reading of POSIX the OpenBSD behavior appears to be non-conforming, but there is active work happening in OpenBSD with respect to signal handling and threads so this should be resolved eventually there.