Signal trapping for SIGINT waits for busy signal to go low
This commit is contained in:
parent
816b29eb18
commit
3d27d47d34
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue