class Parallel::UserInterruptHandler
def kill(thing)
def kill(thing) Process.kill(:KILL, thing) rescue Errno::ESRCH # some linux systems already automatically killed the children at this point # so we just ignore them not being there end
def kill_on_ctrl_c(pids, options)
def kill_on_ctrl_c(pids, options) @to_be_killed ||= [] old_interrupt = nil signal = options.fetch(:interrupt_signal, INTERRUPT_SIGNAL) if @to_be_killed.empty? old_interrupt = trap_interrupt(signal) do warn 'Parallel execution interrupted, exiting ...' @to_be_killed.flatten.each { |pid| kill(pid) } end end @to_be_killed << pids yield ensure @to_be_killed.pop # do not kill pids that could be used for new processes restore_interrupt(old_interrupt, signal) if @to_be_killed.empty? end
def restore_interrupt(old, signal)
def restore_interrupt(old, signal) Signal.trap signal, old end
def trap_interrupt(signal)
def trap_interrupt(signal) old = Signal.trap signal, 'IGNORE' Signal.trap signal do yield if !old || old == "DEFAULT" raise Interrupt else old.call end end old end