aboutsummaryrefslogtreecommitdiffstats
path: root/Library
diff options
context:
space:
mode:
Diffstat (limited to 'Library')
-rw-r--r--Library/Homebrew/cmd/link.rb6
-rw-r--r--Library/Homebrew/cmd/uninstall.rb10
-rw-r--r--Library/Homebrew/cmd/unlink.rb6
-rw-r--r--Library/Homebrew/exceptions.rb12
-rw-r--r--Library/Homebrew/formula.rb15
-rw-r--r--Library/Homebrew/formula_installer.rb26
-rw-r--r--Library/Homebrew/keg.rb12
7 files changed, 79 insertions, 8 deletions
diff --git a/Library/Homebrew/cmd/link.rb b/Library/Homebrew/cmd/link.rb
index a85690ecb..6371c41de 100644
--- a/Library/Homebrew/cmd/link.rb
+++ b/Library/Homebrew/cmd/link.rb
@@ -35,8 +35,10 @@ module Homebrew extend self
next
end
- print "Linking #{keg}... " do
- puts "#{keg.link(mode)} symlinks created"
+ keg.lock do
+ print "Linking #{keg}... " do
+ puts "#{keg.link(mode)} symlinks created"
+ end
end
end
end
diff --git a/Library/Homebrew/cmd/uninstall.rb b/Library/Homebrew/cmd/uninstall.rb
index d719be96a..19ad6eeb5 100644
--- a/Library/Homebrew/cmd/uninstall.rb
+++ b/Library/Homebrew/cmd/uninstall.rb
@@ -7,10 +7,12 @@ module Homebrew extend self
if not ARGV.force?
ARGV.kegs.each do |keg|
- puts "Uninstalling #{keg}..."
- keg.unlink
- keg.uninstall
- rm_opt_link keg.fname
+ keg.lock do
+ puts "Uninstalling #{keg}..."
+ keg.unlink
+ keg.uninstall
+ rm_opt_link keg.fname
+ end
end
else
ARGV.named.each do |name|
diff --git a/Library/Homebrew/cmd/unlink.rb b/Library/Homebrew/cmd/unlink.rb
index 12b037781..37ef8f1da 100644
--- a/Library/Homebrew/cmd/unlink.rb
+++ b/Library/Homebrew/cmd/unlink.rb
@@ -3,8 +3,10 @@ module Homebrew extend self
raise KegUnspecifiedError if ARGV.named.empty?
ARGV.kegs.each do |keg|
- print "Unlinking #{keg}... "
- puts "#{keg.unlink} links removed"
+ keg.lock do
+ print "Unlinking #{keg}... "
+ puts "#{keg.unlink} links removed"
+ end
end
end
end
diff --git a/Library/Homebrew/exceptions.rb b/Library/Homebrew/exceptions.rb
index ae2dd20c4..edd5cf1d1 100644
--- a/Library/Homebrew/exceptions.rb
+++ b/Library/Homebrew/exceptions.rb
@@ -45,6 +45,18 @@ class FormulaUnavailableError < RuntimeError
end
end
+class OperationInProgressError < RuntimeError
+ def initialize name
+ message = <<-EOS.undent
+ Operation already in progress for #{name}
+ Another active Homebrew process is already using #{name}.
+ Please wait for it to finish or terminate it to continue.
+ EOS
+
+ super message
+ end
+end
+
module Homebrew
class InstallationError < RuntimeError
attr :formula
diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb
index 2e072afff..e2fde2ef9 100644
--- a/Library/Homebrew/formula.rb
+++ b/Library/Homebrew/formula.rb
@@ -228,6 +228,21 @@ class Formula
end
end
+ def lock
+ lockpath = HOMEBREW_CACHE_FORMULA/"#{@name}.brewing"
+ @lockfile = lockpath.open(File::RDWR | File::CREAT)
+ unless @lockfile.flock(File::LOCK_EX | File::LOCK_NB)
+ raise OperationInProgressError, @name
+ end
+ end
+
+ def unlock
+ unless @lockfile.nil?
+ @lockfile.flock(File::LOCK_UN)
+ @lockfile.close
+ end
+ end
+
def == b
name == b.name
end
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
diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb
index 3a4d01262..4949d24dc 100644
--- a/Library/Homebrew/keg.rb
+++ b/Library/Homebrew/keg.rb
@@ -61,6 +61,18 @@ class Keg < Pathname
parent.basename.to_s
end
+ def lock
+ path = HOMEBREW_CACHE_FORMULA/"#{fname}.brewing"
+ file = path.open(File::RDWR | File::CREAT)
+ unless file.flock(File::LOCK_EX | File::LOCK_NB)
+ raise OperationInProgressError, fname
+ end
+ yield
+ ensure
+ file.flock(File::LOCK_UN)
+ file.close
+ end
+
def linked_keg_record
@linked_keg_record ||= HOMEBREW_REPOSITORY/"Library/LinkedKegs"/fname
end