Repository navigation
Conversation
The stop signals are held from the start so a SIGTERM that comes early waits for the handler, but on Linux dispatchMain leaves the main thread in sigsuspend with nothing blocked, while the sources register asynchronously. A held signal that came before they had taken over ended the process with no shutdown: every time at the serving line, and about one time in sixteen at the web page line, where sigtermStopsItCleanly sends it. The sources now register on their own queue, and the main thread goes to dispatch only once they have; the handler still runs on the main queue. A new Linux test sends SIGTERM at the serving line. It failed 5 of 5 before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HkbKCyD7z4w52noeFzme3w
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.
On Linux, a SIGTERM that reaches
jetlink-serverwhile it is starting up ends the process outright, with nostopping on SIGTERM, no ordered shutdown and a non-zero exit.ProcessTests.sigtermStopsItCleanlyfails about one run in ten on Linux because of it.Cause
holdStopSignals()blocks SIGINT and SIGTERM before any thread starts, so an early signal stays pending untilstopOnSignalstakes it. But on Linux,dispatchMain()turns the main thread into libdispatch's signal thread, which waits insigsuspendwith an empty mask. Meanwhile theDispatchSourcesignal sources register asynchronously on the manager thread, which is where libdispatch installs its handler. A signal pending before that registration finishes is delivered to the main thread with its default action, so the process ends.Reproduced on Linux by sending SIGTERM as soon as each log line appears (80 runs each):
jetlink-server is servingweb page on port(where the existing test sends it)Fix
In
stopOnSignals:DispatchGroup.dispatchMain()only after the group has emptied.macOS takes the same path, although the race is Linux-only: there a source registers through kqueue and the signal is ignored.
Tests
sigtermDuringStartUpStillStopsCleanlysends SIGTERM at the serving line. It failed 5 of 5 without the fix.swift:6.3.3-jammy:ProcessTestspassed 20 of 20 runs, and the full suite (555 tests) 5 of 5.swift format lint --strictis clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01HkbKCyD7z4w52noeFzme3w