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:
parent
874eb70911
commit
97f9d4c5ef
|
@ -12,6 +12,7 @@ module Vagrant
|
||||||
|
|
||||||
@@busy = false
|
@@busy = false
|
||||||
@@mutex = Mutex.new
|
@@mutex = Mutex.new
|
||||||
|
@@trap_thread = nil
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def busy?
|
def busy?
|
||||||
|
@ -34,6 +35,9 @@ module Vagrant
|
||||||
# busy back to some sane state.
|
# busy back to some sane state.
|
||||||
Busy.busy = false
|
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
|
# And restore the INT trap to the default
|
||||||
Signal.trap("INT", "DEFAULT")
|
Signal.trap("INT", "DEFAULT")
|
||||||
end
|
end
|
||||||
|
@ -41,7 +45,7 @@ module Vagrant
|
||||||
end
|
end
|
||||||
|
|
||||||
def wait_for_not_busy(sleeptime=5)
|
def wait_for_not_busy(sleeptime=5)
|
||||||
Thread.new do
|
@@trap_thread ||= Thread.new do
|
||||||
# Wait while the app is busy
|
# Wait while the app is busy
|
||||||
loop do
|
loop do
|
||||||
break unless busy?
|
break unless busy?
|
||||||
|
@ -50,9 +54,20 @@ module Vagrant
|
||||||
end
|
end
|
||||||
|
|
||||||
# Exit out of the entire script
|
# Exit out of the entire script
|
||||||
|
logger.info "Exiting vagrant..."
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,19 @@ require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
||||||
|
|
||||||
class BusyTest < Test::Unit::TestCase
|
class BusyTest < Test::Unit::TestCase
|
||||||
context "waiting for not busy" do
|
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
|
end
|
||||||
|
|
||||||
context "during an action in a busy block" do
|
context "during an action in a busy block" do
|
||||||
|
@ -27,6 +39,18 @@ class BusyTest < Test::Unit::TestCase
|
||||||
assert !Vagrant.busy?
|
assert !Vagrant.busy?
|
||||||
end
|
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
|
should "report busy to the outside world regardless of thread" do
|
||||||
Thread.new do
|
Thread.new do
|
||||||
Vagrant.busy do
|
Vagrant.busy do
|
||||||
|
|
Loading…
Reference in New Issue