Skip to content

Respect handle_interrupt for default SIGINT.#17533

Open
samuel-williams-shopify wants to merge 1 commit into
ruby:masterfrom
samuel-williams-shopify:fix-sigint-handle-interrupt
Open

Respect handle_interrupt for default SIGINT.#17533
samuel-williams-shopify wants to merge 1 commit into
ruby:masterfrom
samuel-williams-shopify:fix-sigint-handle-interrupt

Conversation

@samuel-williams-shopify

@samuel-williams-shopify samuel-williams-shopify commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Default SIGINT delivery currently calls rb_interrupt() directly, so an Interrupt can be raised inside a Thread.handle_interrupt(SignalException => :never) block. This bypasses the pending interrupt queue used by Thread#raise and other default signal exceptions.

This PR adds a regression test using two Thread::Queue instances to coordinate Process.kill(:INT, Process.pid), then changes the default SIGINT path to enqueue an Interrupt on the main thread. This preserves the default exception class while allowing Thread.handle_interrupt to defer it consistently.

Commits:

  1. Add the failing regression test.
  2. Route default SIGINT through the pending interrupt queue.

Tested with:

make test-all TESTS='ruby/test_thread.rb -n /test_handle_interrupt_masks_sigint/'
make test-all TESTS='ruby/test_thread.rb -n /handle_interrupt/'
make test-all TESTS='ruby/test_signal.rb'

https://bugs.ruby-lang.org/issues/22133

@samuel-williams-shopify samuel-williams-shopify force-pushed the fix-sigint-handle-interrupt branch 3 times, most recently from 77e26f0 to c3d72bc Compare June 28, 2026 09:24
@samuel-williams-shopify

Copy link
Copy Markdown
Contributor Author

@nobu do you have any opinion about this?

@samuel-williams-shopify samuel-williams-shopify force-pushed the fix-sigint-handle-interrupt branch from 90f4758 to 7aaaabf Compare June 29, 2026 00:53
@samuel-williams-shopify samuel-williams-shopify changed the title Respect handle_interrupt for default SIGINT Respect handle_interrupt for default SIGINT. Jun 29, 2026
Default SIGINT delivery used rb_interrupt() directly, which could raise Interrupt inside Thread.handle_interrupt(SignalException => :never). This bypassed the pending interrupt queue used by Thread#raise and other default signal exceptions.

Route default SIGINT through the pending interrupt queue while preserving the traditional no-message Interrupt. Add regression coverage for SIGINT and ruby/spec coverage showing default SIGINT and SIGTERM are maskable by Thread.handle_interrupt.

[[Bug #22133]]
@samuel-williams-shopify samuel-williams-shopify force-pushed the fix-sigint-handle-interrupt branch from 7aaaabf to 3c1705b Compare June 29, 2026 00:55
@samuel-williams-shopify

Copy link
Copy Markdown
Contributor Author

Possible downstream fix / workaround: socketry/async#459

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.

1 participant