[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
This commit is contained in:
Benoit Daloze 2019-06-06 15:52:44 +02:00 коммит произвёл Hiroshi SHIBATA
Родитель 89bd1df895
Коммит 2453d16f5e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: F9CF13417264FAC2
1 изменённых файлов: 8 добавлений и 3 удалений

Просмотреть файл

@ -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