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 --- test/digest/digest/foo.rb | 10 ++++++++ test/digest/test_digest.rb | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 test/digest/digest/foo.rb (limited to 'test') diff --git a/test/digest/digest/foo.rb b/test/digest/digest/foo.rb new file mode 100644 index 0000000000..d576ef00e0 --- /dev/null +++ b/test/digest/digest/foo.rb @@ -0,0 +1,10 @@ +module Digest + Foo = nil + + sleep 0.2 + + remove_const(:Foo) + + class Foo < Class + end +end diff --git a/test/digest/test_digest.rb b/test/digest/test_digest.rb index f4ec0234f1..ccf0a26b90 100644 --- a/test/digest/test_digest.rb +++ b/test/digest/test_digest.rb @@ -208,4 +208,65 @@ module TestDigest end end end + + class TestDigestParen < Test::Unit::TestCase + def test_sha2 + assert_separately(%w[-rdigest], <<-'end;') + assert_nothing_raised { + Digest(:SHA256).new + Digest(:SHA384).new + Digest(:SHA512).new + } + end; + end + + def test_no_lib + assert_separately(%w[-rdigest], <<-'end;') + class Digest::Nolib < Digest::Class + end + + assert_nothing_raised { + Digest(:Nolib).new + } + end; + end + + def test_no_lib_no_def + assert_separately(%w[-rdigest], <<-'end;') + assert_raise(LoadError) { + Digest(:Nodef).new + } + end; + end + + def test_race + assert_separately(['-rdigest', "-I#{File.dirname(__FILE__)}"], <<-'end;') + assert_nothing_raised { + t = Thread.start { + sleep 0.1 + Digest(:Foo).new + } + Digest(:Foo).new + t.join + } + end; + end + + def test_race_mixed + assert_separately(['-rdigest', "-I#{File.dirname(__FILE__)}"], <<-'end;') + assert_nothing_raised { + t = Thread.start { + sleep 0.1 + Digest::Foo.new + } + Digest(:Foo).new + begin + t.join + rescue NoMethodError, NameError + # NoMethodError is highly likely; NameError is listed just in case + end + } + end; + end + end end -- cgit v1.2.3