ruby-changes:69798
From: David <ko1@a...>
Date: Thu, 18 Nov 2021 04:37:51 +0900 (JST)
Subject: [ruby-changes:69798] 8bdb56fcaf (master): [rubygems/rubygems] Protect specs access at a finer level
https://git.ruby-lang.org/ruby.git/commit/?id=8bdb56fcaf From 8bdb56fcaf16ddac761ee5d00cd6cff6b5434640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@r...> 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(-) diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index dd6dd06eef9..10341a9398c 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -67,8 +67,6 @@ class Gem::Installer https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L67 @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 https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L90 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 https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L334 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 https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L519 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 2388354f677..d22b0156e36 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -179,14 +179,18 @@ class Gem::Specification < Gem::BasicSpecification https://github.com/ruby/ruby/blob/trunk/lib/rubygems/specification.rb#L179 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 https://github.com/ruby/ruby/blob/trunk/lib/rubygems/specification.rb#L754 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 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/