diff --git a/plugins/synced_folders/rsync/command/rsync_auto.rb b/plugins/synced_folders/rsync/command/rsync_auto.rb index 0a7a53c6f..f6a939c6d 100644 --- a/plugins/synced_folders/rsync/command/rsync_auto.rb +++ b/plugins/synced_folders/rsync/command/rsync_auto.rb @@ -1,9 +1,11 @@ require "log4r" require 'optparse' +require "thread" require "listen" require "vagrant/action/builtin/mixin_synced_folders" +require "vagrant/util/busy" require_relative "../helper" @@ -86,8 +88,22 @@ module VagrantPlugins @logger.info("Listening via: #{Listen::Adapter.select.inspect}") callback = method(:callback).to_proc.curry[paths] listener = Listen.to(*paths.keys, ignore: ignores, &callback) - listener.start - listener.thread.join + + # Create the callback that lets us know when we've been interrupted + queue = Queue.new + callback = lambda do + # This needs to execute in another thread because Thread + # synchronization can't happen in a trap context. + Thread.new { queue << true }.join + end + + # Run the listener in a busy block so that we can cleanly + # exit once we receive an interrupt. + Vagrant::Util::Busy.busy(callback) do + listener.start + queue.pop + listener.stop if listener.listen? + end 0 end diff --git a/vagrant.gemspec b/vagrant.gemspec index d2d02e444..4f6971e6c 100644 --- a/vagrant.gemspec +++ b/vagrant.gemspec @@ -18,7 +18,7 @@ Gem::Specification.new do |s| s.add_dependency "childprocess", "~> 0.5.0" s.add_dependency "erubis", "~> 2.7.0" s.add_dependency "i18n", "~> 0.6.0" - s.add_dependency "listen", "~> 2.4.0" + s.add_dependency "listen", ">= 2.4.0", "~> 2.7.1" s.add_dependency "log4r", "~> 1.1.9", "< 1.1.11" s.add_dependency "net-ssh", ">= 2.6.6", "< 2.8.0" s.add_dependency "net-scp", "~> 1.1.0"