aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rubygems/specification.rb
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2019-06-06 15:52:44 +0200
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2019-07-31 07:47:00 +0800
commit2453d16f5e44f67a50e1be9b08504a14960610ef (patch)
treed4be909ef01c55770bee46b330d40092242fa333 /lib/rubygems/specification.rb
parent89bd1df895265a3756928b0ab863f01ecb3abd71 (diff)
downloadruby-2453d16f5e44f67a50e1be9b08504a14960610ef.tar.gz
[rubygems/rubygems] Synchronize access to the Gem::Specification::LOAD_CACHE Hash
* It's accessed concurrently, notably when installing a gem with a C extension. https://github.com/rubygems/rubygems/commit/543294d7dd
Diffstat (limited to 'lib/rubygems/specification.rb')
-rw-r--r--lib/rubygems/specification.rb11
1 files changed, 8 insertions, 3 deletions
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
index 88e30e71b3..abb6e0ecfd 100644
--- a/lib/rubygems/specification.rb
+++ b/lib/rubygems/specification.rb
@@ -109,6 +109,7 @@ class Gem::Specification < Gem::BasicSpecification
# rubocop:disable Style/MutableConstant
LOAD_CACHE = {} # :nodoc:
# rubocop:enable Style/MutableConstant
+ LOAD_CACHE_MUTEX = Mutex.new
private_constant :LOAD_CACHE if defined? private_constant
@@ -753,7 +754,9 @@ class Gem::Specification < Gem::BasicSpecification
end
def self._clear_load_cache # :nodoc:
- LOAD_CACHE.clear
+ LOAD_CACHE_MUTEX.synchronize do
+ LOAD_CACHE.clear
+ end
end
def self.each_gemspec(dirs) # :nodoc:
@@ -1105,7 +1108,7 @@ class Gem::Specification < Gem::BasicSpecification
def self.load(file)
return unless file
- _spec = LOAD_CACHE[file]
+ _spec = LOAD_CACHE_MUTEX.synchronize { LOAD_CACHE[file] }
return _spec if _spec
file = file.dup.untaint
@@ -1120,7 +1123,9 @@ class Gem::Specification < Gem::BasicSpecification
if Gem::Specification === _spec
_spec.loaded_from = File.expand_path file.to_s
- LOAD_CACHE[file] = _spec
+ LOAD_CACHE_MUTEX.synchronize do
+ LOAD_CACHE[file] = _spec
+ end
return _spec
end