diff options
author | knu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-10-31 13:21:51 +0000 |
---|---|---|
committer | knu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-10-31 13:21:51 +0000 |
commit | c02fa39463a0c6bf698b01bc610135604aca2ff4 (patch) | |
tree | 7a5a7384ed322e2d8810c7b78e77b456f78236ed /ext/digest/lib | |
parent | 2172b44898a643058eb6a1943943d33635a6db61 (diff) | |
download | ruby-c02fa39463a0c6bf698b01bc610135604aca2ff4.tar.gz |
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
Diffstat (limited to 'ext/digest/lib')
-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 |