Skip to content

Update appbase for POSIX signal handling - #364

Merged
huangminghuang merged 3 commits into
masterfrom
feature/appbase-sigwait-submodule
Jun 4, 2026
Merged

huangminghuang merged 3 commits into
masterfrom
feature/appbase-sigwait-submodule

Conversation

@huangminghuang

@huangminghuang huangminghuang commented Jun 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Update the libraries/appbase submodule to the merged commit from Wire-Network/appbase#5.

What changed

Why

Wire-Network/appbase#5 replaces appbase's Boost.Asio signal handling with a POSIX sigwait-based signal thread.

The old appbase implementation relied on a fragile per-thread signal-mask invariant: appbase created one signal-catching thread before blocking SIGHUP, SIGINT, SIGTERM, and SIGPIPE in the rest of the process, then assumed that thread would keep those signals unblocked for the lifetime of the process.

The macOS failure investigation showed that this invariant can be lost after startup. In an instrumented old-Asio run, the signal-catching thread initially started with those signals unblocked, but later reported the same target set as blocked: INT=1 TERM=1 PIPE=1 HUP=1. The thread was still alive inside its dedicated Asio io_context/kqueue loop, but it was no longer eligible to receive appbase's shutdown/reload signals. After that point, process-directed SIGTERM/SIGHUP stayed pending, no Asio signal-handler entry was logged, no appbase async_wait callback ran, and appbase never called quit().

The appbase fix moves to the standard POSIX sigwait model:

  1. Block the target signals before application worker threads are created.
  2. Let worker threads inherit the blocked signal mask.
  3. Start one dedicated signal thread that keeps those signals blocked and waits with sigwait.
  4. Let sigwait synchronously consume pending process-directed signals from that blocked set.
  5. Dispatch appbase behavior from that known signal owner.

With sigwait, the appbase signal thread no longer needs to preserve a special unblocked mask. The blocked mask is the expected state, and the waiter thread runs only the narrow sigwait loop rather than a full Asio reactor loop. SIGHUP continues to dispatch through appbase's reload path, SIGINT/SIGTERM request graceful quit, and SIGPIPE is explicitly ignored.

The appbase investigation also ruled out the reachable in-process candidates as necessary writers for the old mask flip: sys-vm invoke_with_signal_handler mask operations, Boost.Asio posix_signal_blocker on the signal thread, Boost.Asio scheduler own-thread signal_blocker, fork-only Asio masking, and non-macOS select_reactor paths. Identifying the remaining writer is a useful follow-up, but this submodule update does not depend on it because the sigwait design removes appbase's dependency on an unblocked signal owner.

Related PRs

Testing

Validation performed for Wire-Network/appbase#5 before this submodule update:

  • macOS: cmake --build build/macos-arm64-ci-repro --target appbase_test custom_appbase_test
  • macOS: appbase_test --run_test=posix_signal_handling --report_level=detailed --color_output=no
  • macOS: full appbase_test passed before the final rebase
  • macOS: full custom_appbase_test passed before the final rebase
  • macOS: instrumented old-Asio failure run confirmed the signal-catching thread started with the target signals unblocked, later reported them blocked while still alive in its dedicated io_context, and then stopped receiving SIGTERM/SIGHUP
  • macOS: direct Boost.Asio posix_signal_blocker probe logged zero signal-thread entries before the abort-trap detection
  • macOS: sys-vm invoke_with_signal_handler mask-operation ablation did not prevent the invariant failure
  • macOS: Boost.Asio scheduler own-thread signal_blocker ablation did not prevent the invariant failure
  • Linux sandbox: appbase_test passed
  • Linux sandbox: custom_appbase_test passed
  • Linux sandbox: posix_signal_handling passed

No additional sysio test was run for this PR after the final pointer-only update to the appbase merge commit.

@huangminghuang
huangminghuang requested a review from heifner June 3, 2026 20:52
@huangminghuang
huangminghuang merged commit 075b5be into master Jun 4, 2026
28 checks passed
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