Run only a single trap thread at any given time. Ensure that trap threads are joined after a busy block ends.

This commit is contained in:
Mitchell Hashimoto 2010-02-15 18:37:20 -08:00
parent 874eb70911
commit 97f9d4c5ef
2 changed files with 41 additions and 2 deletions

View File

@ -12,6 +12,7 @@ module Vagrant
@@busy = false
@@mutex = Mutex.new
@@trap_thread = nil
class << self
def busy?
@ -34,6 +35,9 @@ module Vagrant
# busy back to some sane state.
Busy.busy = false
# Make sure that the trap thread completes, if it is running
trap_thread.join if trap_thread
# And restore the INT trap to the default
Signal.trap("INT", "DEFAULT")
end
@ -41,7 +45,7 @@ module Vagrant
end
def wait_for_not_busy(sleeptime=5)
Thread.new do
@@trap_thread ||= Thread.new do
# Wait while the app is busy
loop do
break unless busy?
@ -50,9 +54,20 @@ module Vagrant
end
# Exit out of the entire script
logger.info "Exiting vagrant..."
exit
end
end
# Used for testing
def reset_trap_thread!
@@trap_thread = nil
end
# Returns the trap thread
def trap_thread
@@trap_thread
end
end
end
end

View File

@ -2,7 +2,19 @@ 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
setup do
Vagrant::Busy.reset_trap_thread!
end
should "run in a thread" do
Thread.expects(:new).once.returns(nil)
Vagrant::Busy.wait_for_not_busy
end
should "not start a thread multiple times" do
Thread.expects(:new).once.returns("foo")
Vagrant::Busy.wait_for_not_busy
end
end
context "during an action in a busy block" do
@ -27,6 +39,18 @@ class BusyTest < Test::Unit::TestCase
assert !Vagrant.busy?
end
should "complete the trap thread even if an exception occurs" do
trap_thread = mock("trap_thread")
trap_thread.expects(:join).once
Vagrant::Busy.stubs(:trap_thread).returns(trap_thread)
assert_raise Exception do
Vagrant.busy do
raise Exception
end
end
end
should "report busy to the outside world regardless of thread" do
Thread.new do
Vagrant.busy do