diff options
Diffstat (limited to 'lib/rubygems/installer.rb')
-rw-r--r-- | lib/rubygems/installer.rb | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index 939bc9693d..0ccf7ad52f 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -9,6 +9,7 @@ require 'rubygems/package' require 'rubygems/ext' require 'rubygems/user_interaction' require 'fileutils' +require 'thread' ## # The installer installs the files contained in the .gem into the Gem.home. @@ -32,6 +33,14 @@ class Gem::Installer ENV_PATHS = %w[/usr/bin/env /bin/env] ## + # The builder shells-out to run various commands after changing the + # directory. This means multiple installations cannot be allowed to build + # extensions in parallel as they may change each other's directories leading + # to broken extensions or failed installations. + + CHDIR_MUTEX = Mutex.new # :nodoc: + + ## # Raised when there is an error while building extensions. # class ExtensionBuildError < Gem::InstallError; end @@ -675,11 +684,13 @@ TEXT begin FileUtils.mkdir_p dest_path - Dir.chdir extension_dir do - results = builder.build(extension, gem_dir, dest_path, - results, @build_args) + CHDIR_MUTEX.synchronize do + Dir.chdir extension_dir do + results = builder.build(extension, gem_dir, dest_path, + results, @build_args) - say results.join("\n") if Gem.configuration.really_verbose + say results.join("\n") if Gem.configuration.really_verbose + end end rescue extension_build_error(extension_dir, results.join("\n"), $@) |