class InterruptHandler

Provides a handler for interrupt signals (SIGINT), allowing the application to finish what it's currently working on.

Attributes

isolate_signals[RW]
reenable_on_interrupt[RW]
signal_received[RW]

Public Class Methods

disable!() click to toggle source

Disable interrupt isolation.

# File lib/overcommit/interrupt_handler.rb, line 71
def disable!
  instance.isolate_signals = false
end
disable_until_finished_or_interrupted() { || ... } click to toggle source

Provide a way to allow a single Ctrl-C interrupt to happen and atomically re-enable interrupt protections once that interrupt is propagated.

This prevents a race condition where code like the following:

begin
  InterruptHandler.disable!
  ... do stuff ...
rescue Interrupt
  ... handle it ...
ensure
  InterruptHandler.enable!
end

…could have the `enable!` call to the interrupt handler not called in the event another interrupt was received in between the interrupt being handled and the `ensure` block being entered.

Thus you should always write:

begin
  InterruptHandler.disable_until_finished_or_interrupted do
    ... do stuff ...
  end
rescue Interrupt
  ... handle it ...
rescue
  ... handle any other exceptions ...
end
# File lib/overcommit/interrupt_handler.rb, line 62
def disable_until_finished_or_interrupted
  instance.reenable_on_interrupt = true
  instance.isolate_signals = false
  yield
ensure
  instance.isolate_signals = true
end
enable!() click to toggle source

Enable interrupt isolation.

# File lib/overcommit/interrupt_handler.rb, line 76
def enable!
  instance.isolate_signals = true
end
isolate_from_interrupts() { || ... } click to toggle source

Enable interrupt isolation while executing the provided block.

@yield block to execute with interrupt isolation

# File lib/overcommit/interrupt_handler.rb, line 83
def isolate_from_interrupts
  instance.signal_received = false
  instance.isolate_signals = true
  result = yield
  instance.isolate_signals = false
  result
end
new() click to toggle source

Initialize safe interrupt signal handling.

# File lib/overcommit/interrupt_handler.rb, line 13
def initialize
  self.isolate_signals = false
  self.signal_received = false
  self.reenable_on_interrupt = false

  Signal.trap('INT') do
    if isolate_signals
      self.signal_received = true
    else
      if reenable_on_interrupt
        self.reenable_on_interrupt = false
        self.isolate_signals = true
      end

      raise Interrupt # Allow interrupt to propagate to code
    end
  end
end