From c02fa39463a0c6bf698b01bc610135604aca2ff4 Mon Sep 17 00:00:00 2001 From: knu Date: Fri, 31 Oct 2014 13:21:51 +0000 Subject: Make Digest() thread-safe. * ext/digest/lib/digest.rb (Digest()): This function should now be thread-safe. If you have a problem with regard to on-demand loading under a multi-threaded environment, preload "digest/*" modules on boot or use this method instead of directly referencing Digest::*. [Bug #9494] cf. https://github.com/aws/aws-sdk-ruby/issues/525 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48213 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/digest/lib/digest.rb | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'ext/digest/lib') diff --git a/ext/digest/lib/digest.rb b/ext/digest/lib/digest.rb index 5f7ebc2237..ef43c46ac3 100644 --- a/ext/digest/lib/digest.rb +++ b/ext/digest/lib/digest.rb @@ -1,6 +1,9 @@ require 'digest.so' module Digest + # A mutex for Digest(). + REQUIRE_MUTEX = Mutex.new + def self.const_missing(name) # :nodoc: case name when :SHA256, :SHA384, :SHA512 @@ -76,15 +79,30 @@ end # call-seq: # Digest(name) -> digest_subclass # -# Returns a Digest subclass by +name+. +# Returns a Digest subclass by +name+ in a thread-safe manner even +# when on-demand loading is involved. # # require 'digest' # # Digest("MD5") # # => Digest::MD5 # -# Digest("Foo") +# Digest(:SHA256) +# # => Digest::SHA256 +# +# Digest(:Foo) # # => LoadError: library not found for class Digest::Foo -- digest/foo def Digest(name) - Digest.const_get(name) + const = name.to_sym + Digest::REQUIRE_MUTEX.synchronize { + # Ignore autoload's because it is void when we have #const_missing + Digest.const_missing(const) + } +rescue LoadError + # Constants do not necessarily rely on digest/*. + if Digest.const_defined?(const) + Digest.const_get(const) + else + raise + end end -- cgit v1.2.3