From 447f407b0b25b0c5347643e1cee157659b985708 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 16 Apr 2014 16:00:57 -0700 Subject: [PATCH] providers/docker: use a mutex for intra-process lock --- plugins/providers/docker/provider.rb | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/plugins/providers/docker/provider.rb b/plugins/providers/docker/provider.rb index 35a1e8724..81fcd7e56 100644 --- a/plugins/providers/docker/provider.rb +++ b/plugins/providers/docker/provider.rb @@ -1,5 +1,6 @@ require "digest/md5" require "fileutils" +require "thread" require "log4r" @@ -8,6 +9,8 @@ require "vagrant/util/silence_warnings" module VagrantPlugins module DockerProvider class Provider < Vagrant.plugin("2", :provider) + @@host_vm_mutex = Mutex.new + def initialize(machine) @logger = Log4r::Logger.new("vagrant::provider::docker") @machine = machine @@ -94,11 +97,23 @@ module VagrantPlugins # This acquires a lock on the host VM. def host_vm_lock hash = Digest::MD5.hexdigest(host_vm.data_dir.to_s) - @machine.env.lock(hash) do - return yield + + # We do a process-level mutex on the outside, since we can + # wait for that a short amount of time. Then, we do a process lock + # on the inside, which will raise an exception if locked. + host_vm_mutex.synchronize do + @machine.env.lock(hash) do + return yield + end end end + # This is a process-local mutex that can be used by parallel + # providers to lock the host VM access. + def host_vm_mutex + @@host_vm_mutex + end + # This says whether or not Docker will be running within a VM # rather than directly on our system. Docker needs to run in a VM # when we're not on Linux, or not on a Linux that supports Docker.