From 8bdb56fcaf16ddac761ee5d00cd6cff6b5434640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 4 Nov 2021 13:40:53 +0100 Subject: [rubygems/rubygems] Protect specs access at a finer level https://github.com/rubygems/rubygems/commit/c8cc053bde --- lib/rubygems/installer.rb | 12 ++---------- lib/rubygems/specification.rb | 16 ++++++++++------ 2 files changed, 12 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index dd6dd06eef..10341a9398 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -67,8 +67,6 @@ class Gem::Installer @path_warning = false - @install_lock = Thread::Mutex.new - class << self # # Changes in rubygems to lazily loading `rubygems/command` (in order to @@ -92,12 +90,6 @@ class Gem::Installer attr_accessor :path_warning - ## - # Certain aspects of the install process are not thread-safe. This lock is - # used to allow multiple threads to install Gems at the same time. - - attr_reader :install_lock - ## # Overrides the executable format. # @@ -342,7 +334,7 @@ class Gem::Installer say spec.post_install_message if options[:post_install_message] && !spec.post_install_message.nil? - Gem::Installer.install_lock.synchronize { Gem::Specification.reset } + Gem::Specification.reset run_post_install_hooks @@ -527,7 +519,7 @@ class Gem::Installer end def generate_plugins # :nodoc: - latest = Gem::Installer.install_lock.synchronize { Gem::Specification.latest_spec_for(spec.name) } + latest = Gem::Specification.latest_spec_for(spec.name) return if latest && latest.version > spec.version ensure_writable_dir @plugins_dir diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index 2388354f67..d22b0156e3 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -179,14 +179,18 @@ class Gem::Specification < Gem::BasicSpecification end def self.clear_specs # :nodoc: - @@all = nil - @@stubs = nil - @@stubs_by_name = {} - @@spec_with_requirable_file = {} - @@active_stub_with_requirable_file = {} + @@all_specs_mutex.synchronize do + @@all = nil + @@stubs = nil + @@stubs_by_name = {} + @@spec_with_requirable_file = {} + @@active_stub_with_requirable_file = {} + end end private_class_method :clear_specs + @@all_specs_mutex = Thread::Mutex.new + clear_specs # Sentinel object to represent "not found" stubs @@ -750,7 +754,7 @@ class Gem::Specification < Gem::BasicSpecification attr_accessor :specification_version def self._all # :nodoc: - @@all ||= Gem.loaded_specs.values | stubs.map(&:to_spec) + @@all_specs_mutex.synchronize { @@all ||= Gem.loaded_specs.values | stubs.map(&:to_spec) } end def self.clear_load_cache # :nodoc: -- cgit v1.2.1