diff options
Diffstat (limited to 'ext/digest')
-rw-r--r-- | ext/digest/lib/digest.rb | 24 |
1 files changed, 21 insertions, 3 deletions
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 |