aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/formula_installer.rb
diff options
context:
space:
mode:
authorJack Nagel2013-01-23 00:26:25 -0600
committerJack Nagel2013-01-26 12:14:45 -0600
commit37a56fa5133e287c765f70edbfc7753c8e8e27b3 (patch)
treee50d56c234a41a30711f7e297077cfce98acaf4a /Library/Homebrew/formula_installer.rb
parentea4188ecda25195421054973f326b14307e789fa (diff)
downloadbrew-37a56fa5133e287c765f70edbfc7753c8e8e27b3.tar.bz2
FormulaInstaller: implement installation locks
FormulaInstaller now attempts to take a lock on a "foo.brewing" file for the formula and all of its dependencies before attempting installation. The lock is an advisory lock implemented using flock(), and as such it only locks out other processes that attempt to take the lock. It also means that it is never necessary to manually remove the lock file, because the lock is not enforced by I/O. The uninstall, link, and unlink commands all learn to respect this lock as well, so that the installation cannot be corrupted by a concurrent Homebrew process, and keg operations cannot occur simultaneously.
Diffstat (limited to 'Library/Homebrew/formula_installer.rb')
-rw-r--r--Library/Homebrew/formula_installer.rb26
1 files changed, 26 insertions, 0 deletions
diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb
index 373440ba8..b24641e55 100644
--- a/Library/Homebrew/formula_installer.rb
+++ b/Library/Homebrew/formula_installer.rb
@@ -22,6 +22,7 @@ class FormulaInstaller
@@attempted ||= Set.new
+ lock
check_install_sanity
end
@@ -226,6 +227,8 @@ class FormulaInstaller
print "#{f.prefix}: #{f.prefix.abv}"
print ", built in #{pretty_duration build_time}" if build_time
puts
+
+ unlock if hold_locks?
end
def build_time
@@ -463,6 +466,29 @@ class FormulaInstaller
check_jars
check_non_libraries
end
+
+ private
+
+ def hold_locks?
+ @hold_locks || false
+ end
+
+ def lock
+ if (@@locked ||= []).empty?
+ f.recursive_deps.each { |d| @@locked << d } unless ignore_deps
+ @@locked.unshift(f)
+ @@locked.each(&:lock)
+ @hold_locks = true
+ end
+ end
+
+ def unlock
+ if hold_locks?
+ @@locked.each(&:unlock)
+ @@locked.clear
+ @hold_locks = false
+ end
+ end
end