Repository navigation
fix: give SIGINT and SIGTERM back to Python after the JVM starts - #26
Merged
Merged
Conversation
JPype's default startJVM(interrupt=False) installs JVM handlers for SIGINT and SIGTERM. Ctrl-C then only set a pending flag and never woke a main thread blocked in time.sleep, Lock.acquire or queue.get, and SIGTERM aborted with status -6 (jpype-project/jpype#1497). start_jvm() now re-installs Python's handlers right after the JVM starts, on the main thread, unless interrupt=True. Ported from humemai/arcadedb-embedded-python#494. Refs #19. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 23, 2026
Open
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.
Ctrl-C does not stop a script that is blocked in one long call in the main thread on the JVM wheel, and
kill -TERMaborts the process with status -6. This ports the fix of humemai/arcadedb-embedded-python#494 (merged as a9ed1284cf) to this repo. It is the Ctrl-C item of the Python runtime fixes group in #19.Why
With the default
interrupt=False,jpype.startJVMinstallssun.misc.Signalhandlers for SIGINT and SIGTERM, which replace Python's handlers at the operating-system level. A SIGINT goes to the JVM, whose signal-dispatcher thread tells Python later (PyErr_SetInterruptEx). That sets the "interrupt pending" flag but wakes nobody: the main thread got EINTR before the flag was set, went back intotime.sleep(), and theKeyboardInterruptwaited for the end of the call. With no Python handler for SIGTERM the same path crashes the process (jpype-project/jpype#1497). Data was never affected. The native wheel has no JPype and no Java handler, so it was never affected.What
start_jvm()callssignal.signal(sig, signal.getsignal(sig))for SIGINT and SIGTERM right after the JVM starts, wheninterruptis notTrue(main thread only, skipped elsewhere). That puts the operating-system disposition back, so both signals behave as in a script without a JVM. A Java call in progress is still not interrupted by Ctrl-C (theKeyboardInterruptarrives when it returns);kill -TERMends the process with -15 and runs no Python cleanup (committed data is intact, the next open replays the log).interrupt=Trueis unchanged. Thestart_jvmdocstring is updated; this repo has no user docs pages yet (the Antora component is still open in #23), so there is no known-issues or API page to change.Before and after
Numbers from #494 (wheel 26.10.2.post1 environment, child with a transaction holding one insert, SIGINT 0.3 s after the transaction opened, bound 10 s):
time.sleep(30)in the main thread, transaction open, SIGINTKeyboardInterruptcaughtTests
tests/test_sigint.pygetstest_ctrl_c_wakes_a_long_blocking_call_with_a_transaction_open(a singletime.sleep(60)inside a transaction, SIGINT, must exit within 20 s withKeyboardInterrupt, rollback,finally,atexit) andtest_sigterm_ends_the_process_with_status_minus_15. The bounds are hang detectors, not latency bounds.Run locally with
uv runagainst the 26.11.1.dev0 wheel of humemai/arcadedb-embedded-python overlaid with this branch'ssrc/arcadedb_embedded/*.py(no wheel was built from this tree):test_sigint.py,test_jvm.py,test_jvm_args.py, 22 passed. On the unmodified code the two new tests fail (child still running 20 s after SIGINT; exit -6 on SIGTERM) and the other 20 pass. black, isort and bandit are clean. CI builds the real wheel.Refs #19, humemai/arcadedb-embedded-python#494.
🤖 Generated with Claude Code