Signal trapping for SIGINT waits for busy signal to go low

This commit is contained in:
Mitchell Hashimoto 2010-02-15 17:56:48 -08:00
parent 816b29eb18
commit 3d27d47d34
4 changed files with 51 additions and 3 deletions

View File

@ -4,8 +4,10 @@ module Vagrant
def execute!
@vm.invoke_callback(:before_import)
Busy.busy do
logger.info "Importing base VM (#{Vagrant.config[:vm][:base]})..."
@vm.vm = VirtualBox::VM.import(File.expand_path(Vagrant.config[:vm][:base]))
end
@vm.invoke_callback(:after_import)
end

View File

@ -8,6 +8,8 @@ module Vagrant
end
class Busy
extend Vagrant::Util
@@busy = false
@@mutex = Mutex.new
@ -23,15 +25,34 @@ module Vagrant
def busy(&block)
@@mutex.synchronize do
begin
Signal.trap("INT") { wait_for_not_busy }
Busy.busy = true
yield
runner = Thread.new(block) { block.call }
runner.join
ensure
# In the case an exception is thrown, make sure we restore
# busy back to some sane state.
Busy.busy = false
# And restore the INT trap to the default
Signal.trap("INT", "DEFAULT")
end
end
end
def wait_for_not_busy(sleeptime=5)
Thread.new do
# Wait while the app is busy
loop do
break unless busy?
logger.info "Waiting for vagrant to clean itself up..."
sleep sleeptime
end
# Exit out of the entire script
exit
end
end
end
end
end

View File

@ -7,6 +7,11 @@ class ImportActionTest < Test::Unit::TestCase
VirtualBox::VM.stubs(:import)
end
should "run in a busy block" do
Vagrant::Busy.expects(:busy).once
@import.execute!
end
should "invoke before/after callbacks around the import" do
callback_seq = sequence("callback_seq")
@mock_vm.expects(:invoke_callback).with(:before_import).once.in_sequence(callback_seq)

View File

@ -1,6 +1,10 @@
require File.join(File.dirname(__FILE__), '..', 'test_helper')
class BusyTest < Test::Unit::TestCase
context "waiting for not busy" do
# TODO: Need to test this method
end
context "during an action in a busy block" do
should "report as busy" do
Vagrant.busy do
@ -33,5 +37,21 @@ class BusyTest < Test::Unit::TestCase
# While the above thread is executing vagrant should be busy
assert Vagrant.busy?
end
should "run the action in a new thread" do
runner_thread = nil
Vagrant.busy do
runner_thread = Thread.current
end
assert_not_equal Thread.current, runner_thread
end
should "trap INT" do
trap_seq = sequence("trap_seq")
Signal.expects(:trap).with("INT", anything).once.in_sequence(trap_seq)
Signal.expects(:trap).with("INT", "DEFAULT").once.in_sequence(trap_seq)
Vagrant.busy do; end
end
end
end