Skip to content

Instantly share code, notes, and snippets.

@jakubwro
Created November 9, 2023 19:10
Show Gist options
  • Save jakubwro/03418b75aa0fc5742e6a40a0fe97fcbc to your computer and use it in GitHub Desktop.
Save jakubwro/03418b75aa0fc5742e6a40a0fe97fcbc to your computer and use it in GitHub Desktop.
Force Julia to handle SIGINT in a certain task v2
# BEGIN PIRACY
function Core.Task(@nospecialize(f), reserved_stack::Int=0; interrupts = false)
new_f = if interrupts f else () -> disable_sigint(f) end
Core._Task(new_f, reserved_stack, Base.ThreadSynchronizer())
end
# END PIRACY
const INTERRUPT_HANDLER_SLEEP_SECONDS = 0.3333
function handle_interrupt()
@info "Handling interrupt."
end
function interrupt_handler_loop()
@info "Handler thread id is $(Threads.threadid())"
while true
try
sleep(INTERRUPT_HANDLER_SLEEP_SECONDS)
catch err
if err isa InterruptException
handle_interrupt()
else
rethrow()
end
end
end
end
interrupt_handler_task = Task(interrupt_handler_loop, 0; interrupts = true)
Threads.schedule(interrupt_handler_task)
errormonitor(interrupt_handler_task)
non_interruptible_task = Threads.@spawn :interactive begin
while true
sleep(0.1)
end
end
> julia -t 1,1
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.9.3 (2023-08-24)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> # BEGIN PIRACY
function Core.Task(@nospecialize(f), reserved_stack::Int=0; interrupts = false)
new_f = if interrupts f else () -> disable_sigint(f) end
Core._Task(new_f, reserved_stack, Base.ThreadSynchronizer())
end
julia> # END PIRACY
const INTERRUPT_HANDLER_SLEEP_SECONDS = 0.3333
0.3333
julia> function handle_interrupt()
@info "Handling interrupt."
end
handle_interrupt (generic function with 1 method)
julia> function interrupt_handler_loop()
@info "Handler thread id is $(Threads.threadid())"
while true
try
sleep(INTERRUPT_HANDLER_SLEEP_SECONDS)
catch err
if err isa InterruptException
handle_interrupt()
else
rethrow()
end
end
end
end
interrupt_handler_loop (generic function with 1 method)
julia> interrupt_handler_task = Task(interrupt_handler_loop, 0; interrupts = true)
Task (runnable) @0x000000010a677b70
julia> Threads.schedule(interrupt_handler_task)
[ Info: Handler thread id is 1
Task (runnable) @0x000000010a677b70
julia> errormonitor(interrupt_handler_task)
Task (runnable) @0x000000010a677b70
julia> non_interruptible_task = Threads.@spawn :interactive begin
while true
sleep(0.1)
end
end
Task (runnable) @0x000000010aa15f50
julia>
julia> sleep(10)
^C[ Info: Handling interrupt.
^C[ Info: Handling interrupt.
^C[ Info: Handling interrupt.
^C[ Info: Handling interrupt.
^C[ Info: Handling interrupt.
^C[ Info: Handling interrupt.
^C[ Info: Handling interrupt.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment