Skip to content

WIP: User-defined signal handling #59147

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 10 commits into
base: master
Choose a base branch
from
Draft

WIP: User-defined signal handling #59147

wants to merge 10 commits into from

Conversation

omus
Copy link
Member

@omus omus commented Jul 29, 2025

Add a signal handler interface to Julia to trigger user defined code. The signals here are only received via an AsyncCondition to avoid issues with code which would be signal unsafe.

I looked into using libuv's signal handing but ended up not going with that approach as the libuv signal handling resets the signal handler back to SIG_DFL when there are no more signal handlers. There was an issue about this (libuv/libuv#2435) which was fixed in libuv/libuv#4216 and later reverted. It turns out that it's hard to restore an old signal handler in a cross platform way (see libuv/libuv#4299) which is why I opted to make jl_install_default_signal_handler.

Fixes:

Related to:

@omus omus changed the title User-defined signal handling WIP: User-defined signal handling Jul 29, 2025
@omus
Copy link
Member Author

omus commented Jul 29, 2025

I've got a working prototype for user-defined signal handling working well on macOS. I'm pushing some of the more basic code first to flush out any platform specific bugs.

@gbaraldi
Copy link
Member

I'm not sure if this is the expected path we want to go here. Specifically because running julia code inside of a signal handler might be very difficult (it's unclear what async signal safe would be in julia)

@omus
Copy link
Member Author

omus commented Jul 29, 2025

I'm not sure if this is the expected path we want to go here. Specifically because running julia code inside of a signal handler might be very difficult (it's unclear what async signal safe would be in julia)

I haven't pushed any of the signal handling code here yet. The approach taken is to use a uv_async_t to notify a Julia thread that a signal has fired. I'll push the rest of the code shortly.

@gbaraldi
Copy link
Member

@jpsamaroo is probably interested in what this means. #49541

@omus
Copy link
Member Author

omus commented Jul 29, 2025

TODO:

I'll be on holidays for a bit after today so I'll probably not respond until I'm back

Comment on lines +77 to +96
function signal_router(condition::AsyncCondition)
while isopen(condition)
wait(condition) # Wait until notified by `jl_signal_router_condition`
signum = ccall(:jl_consume_user_signal, Cint, ())

# Process all queued signals while the thread is active
while signum != -1
signal_handler = @lock _SIGNAL_HANDLER_LOCK begin
get(_SIGNAL_HANDLER, signum, nothing)
end

if !isnothing(signal_handler)
invokelatest(signal_handler, signum)
end

signum = ccall(:jl_consume_user_signal, Cint, ())
end
end
return nothing
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably automatically deregister the signal handler if anything in here throws, so that we don't infinitely accumulate signal messages in the runtime.

@jpsamaroo
Copy link
Member

This looks awesome! Have you tested at all how this behaves with multiple threads, but a single task on thread 1 (where we do I/O) is blocked in while true; end? It's not a huge deal if it doesn't call the signal handlers (I assume no I/O will run at all in that situation), would just be good to know.

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.

3 participants