Repository navigation
frontend: Quit on SIGTERM while outputs run or a dialog waits - #1403
Merged
Merged
Conversation
A new Tier 4 phase (run_tier4.py --only shutdown, also part of the full run) checks two stop requests: - SIGTERM while a Simple output recording runs, with "Show confirmation on exit while outputs are active" left on, the default. OBS must quit within 30 s and leave a finished recording (one file, ffprobe duration at least 2 s). - SIGTERM while the "encoder missing" dialog that the main window opens during its startup is waiting (the profile names an encoder the build does not have). OBS must quit within 30 s with a clean shutdown in its log and no crash. systemctl stop, logind at shutdown and kill send SIGTERM. Nobody can answer a dialog for them, so OBS stays up until the service manager kills it: a recording is cut off and the next start is an unclean one (obsproject/obs-studio#10011). The other Tier 4 phases turn the exit confirmation off, so they never saw this. Fails on master, 3 of 6: "OBS quits on SIGTERM while recording: recording active=True; still running 30 s after SIGTERM", the MKV is 0 bytes, and "OBS quits on SIGTERM during the startup dialog: still running 30 s after SIGTERM". Refs obs-rust#1402.
SIGTERM ran OBSApp::quit(), which closes the main window. Two cases ignored it, and systemctl stop, logind at shutdown and kill send SIGTERM with nobody there to answer a dialog, so OBS stayed up until the sender killed it (obsproject/obs-studio#10011): - With an output active and "Show confirmation on exit while outputs are active" on (the default), OBSBasic::closeEvent() ignored the close and opened the "exit anyway?" dialog. The recording was cut off when OBS was killed (0 bytes, or no duration) and the next start was an unclean one. - While a modal dialog waited, for example the "encoder missing" one the main window opens during its startup, the quit ended nothing: the dialog runs its own event loop, and before the main event loop has started quit() does nothing at all. processSigTerm() now marks the main window to close without the exit confirmation, so closeWindow() runs as when it is answered with Yes: it stops the outputs and waits for the recording to finish. If a modal dialog is open, it dismisses the dialogs and quits once their loops have returned; main() quits after a startup that SIGTERM interrupted, as soon as the main event loop runs. Closing the window, Exit in the menus and SIGINT are unchanged. run_tier4.py --only shutdown: 6 of 6, three runs. With a recording running, SIGTERM quits in about 1 s and leaves a complete MKV (ffprobe duration 4.97 s). Fixes obs-rust#1402.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1402
What and why
SIGTERM now quits OBS while it records or streams, also with "Show confirmation on exit while outputs are active" on (the default), and finishes the recording. It also quits while a modal dialog waits, including during startup. Before, OBS stayed up until the sender killed it, which cut the recording off (upstream obsproject/obs-studio#10011, reported by Mikilio).
OBSApp::processSigTerm()calledquit(), which closes the main window. With an output active,OBSBasic::closeEvent()ignored that close and opened the "exit anyway?" dialog. systemctl stop, logind at shutdown and kill send SIGTERM, and nobody answers that dialog.quit()does nothing at all.processSigTerm()now callsOBSBasic::closeWithoutPrompt(), after whichshouldPromptForClose()is false.closeWindow()then runs as when the dialog is answered with Yes: it stops the outputs and waits for the recording to finish (the wait from frontend: Recording shutdown waits for the stop signal instead of polling the UI thread (#1283) #1342/fix: recording shutdown waits for inactive after deactivate #1392).processSigTerm()dismisses it and quits once its loop has returned.main()quits right after a startup that SIGTERM interrupted, as soon as the main event loop runs. Startup itself is not cut short, so nothing it still uses is freed under it.Headless (private Xvfb, private D-Bus, fresh HOME), driven over obs-websocket: Simple output, x264, MKV, exit confirmation on.
RED → GREEN
test: Tier 4 checks that SIGTERM while recording quits OBS. A new Tier 4 phase (run_tier4.py --only shutdown, also part of the full run) records with the exit confirmation on, sends SIGTERM and expects OBS gone within 30 s with one finished recording (ffprobe duration at least 2 s). Then it starts OBS with a profile whose encoder is missing, sends SIGTERM while that dialog is up and expects a clean shutdown. On master: 3 of 6 fail ("still running 30 s after SIGTERM (the exit confirmation dialog is open)"; a 0-byte MKV; "still running 30 s after SIGTERM" during the startup dialog). The other Tier 4 phases turn the confirmation off, so they never saw this.frontend: Quit on SIGTERM while outputs run or a dialog waits. 6 of 6, three runs. Full build (C libobs lane) and full ctest -j4 (private Xvfb, private D-Bus, fresh HOME, systemlibobs-openglmasked): 303/303; the only skipped case isopen_crashes_without_obs_core, as on master. The change is frontend-only.Checklist
master-W..., ratchets): noneAI note: Claude Code (Claude Opus 5.5) wrote the code, the test, the commit messages and this text under the submitter's direction, and ran the tests above on the submitter's machines.