You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In #7339 (comment) I mentioned a new method Process.on_interrupt as a platform-independent replacement of Signal::INT.trap and friends. Here, an interrupt is defined to be whatever Ctrl+C in a terminal produces. On Windows the method is backed by SetControlCtrlHandler:
# consoleapi.crlibLibCCTRL_C_EVENT=0aliasPHANDLER_ROUTINE=DWORD->BOOLfunSetConsoleCtrlHandler(handlerRoutine : PHANDLER_ROUTINE, add : BOOL) : BOOLendclassProcess@@handler=Proc(Nil).new { }
@@interrupt_handler : LibC::PHANDLER_ROUTINE?
defself.on_interrupt(&@@handler : ->) : Nil@@interrupt_handler.try { |handler| LibC.SetConsoleCtrlHandler(handler, 0) }
@@interrupt_handler= handler =LibC::PHANDLER_ROUTINE.new do |dwCtrlType|
next0unless dwCtrlType ==LibC::CTRL_C_EVENTbegin@@handler.call
rescue ex
ex.inspect_with_backtrace(STDERR)
STDERR.puts("FATAL: uncaught exception while processing interrupt handler, exiting")
STDERR.flush
LibC._exit(1)
end1endLibC.SetConsoleCtrlHandler(handler, 1)
end# this always disables the user-defined interrupt handler, so# perhaps a different method name is more suitabledefself.on_interrupt(ignore : Bool) : Nil@@interrupt_handler.try { |handler| LibC.SetConsoleCtrlHandler(handler, 0) }
LibC.SetConsoleCtrlHandler(nil, ignore ?1 : 0)
endend
On Unix-like systems, these methods simply forward to Signal::INT:
Spec runners for example can be stopped early by an interrupt request, after which they print all the already executed spec results and then exit. On Windows this does not happen yet because the Signal::INT.trap call is wrapped inside a conditional macro, but this method makes it possible.
This minimal implementation is inadequate because the interrupt handler always runs on a newly spun thread on Windows. We definitely don't want to suddenly force people to start writing thread-safe code, when fiber safety suffices for Signal::INT. Ideally, the handler should be executed on a dedicated fiber on the same thread as the one that called Process.on_interrupt. Is this possible?
Also I am wondering if the exit status in case of an uncaught exception should be 0x40000015 (STATUS_FATAL_APP_EXIT) rather than 1. (This applies to other similar abnormal terminations in the standard library too.)
The text was updated successfully, but these errors were encountered:
In #7339 (comment) I mentioned a new method
Process.on_interrupt
as a platform-independent replacement ofSignal::INT.trap
and friends. Here, an interrupt is defined to be whatever Ctrl+C in a terminal produces. On Windows the method is backed bySetControlCtrlHandler
:On Unix-like systems, these methods simply forward to
Signal::INT
:Spec runners for example can be stopped early by an interrupt request, after which they print all the already executed spec results and then exit. On Windows this does not happen yet because the
Signal::INT.trap
call is wrapped inside a conditional macro, but this method makes it possible.This minimal implementation is inadequate because the interrupt handler always runs on a newly spun thread on Windows. We definitely don't want to suddenly force people to start writing thread-safe code, when fiber safety suffices for
Signal::INT
. Ideally, the handler should be executed on a dedicated fiber on the same thread as the one that calledProcess.on_interrupt
. Is this possible?Also I am wondering if the exit status in case of an uncaught exception should be 0x40000015 (
STATUS_FATAL_APP_EXIT
) rather than 1. (This applies to other similar abnormal terminations in the standard library too.)The text was updated successfully, but these errors were encountered: