class Vagrant::Util::Busy

Utility class which allows blocks of code to be marked as “busy” with a specified interrupt handler. During busy areas of code, it is often undesirable for SIGINTs to immediately kill the application. This class is a helper to cleanly register callbacks to handle this situation.

Public Class Methods

busy(sig_callback) { || ... } click to toggle source

Mark a given block of code as a “busy” block of code, which will register a SIGINT handler for the duration of the block. When a SIGINT occurs, the ‘sig_callback` proc will be called. It is up to the callback to behave properly and exit the application.

# File lib/vagrant/util/busy.rb, line 17
def busy(sig_callback)
  register(sig_callback)
  return yield
ensure
  unregister(sig_callback)
end
fire_callbacks() click to toggle source

Fires all the registered callbacks.

# File lib/vagrant/util/busy.rb, line 48
def fire_callbacks
  registered.reverse.each { |r| r.call }
end
register(sig_callback) click to toggle source

Registers a SIGINT handler. This typically is called from {busy}. Callbacks are only registered once, so calling this multiple times with the same callback has no consequence.

# File lib/vagrant/util/busy.rb, line 27
def register(sig_callback)
  @@mutex.synchronize do
    registered << sig_callback
    registered.uniq!

    # Register the handler if this is our first callback.
    Signal.trap("INT") { fire_callbacks } if registered.length == 1
  end
end
registered() click to toggle source

Helper method to get access to the class variable. This is mostly exposed for tests. This shouldn’t be mucked with directly, since it’s structure may change at any time.

# File lib/vagrant/util/busy.rb, line 55
def registered; @@registered; end
unregister(sig_callback) click to toggle source

Unregisters a SIGINT handler.

# File lib/vagrant/util/busy.rb, line 38
def unregister(sig_callback)
  @@mutex.synchronize do
    registered.delete(sig_callback)

    # Remove the signal trap if no more registered callbacks exist
    Signal.trap("INT", "DEFAULT") if registered.empty?
  end
end