From 52325f6bf868c5efa80fbcf06d139a31816251fb Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 24 Nov 2005 05:43:27 +0000 Subject: Sever infinite loop for mutual dependencies. Closes #2997. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3181 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activesupport/lib/active_support/dependencies.rb | 22 +++++++++++++++------- activesupport/test/dependencies/mutual_one.rb | 2 ++ activesupport/test/dependencies/mutual_two.rb | 2 ++ .../test/dependencies/raises_exception.rb | 1 + activesupport/test/dependencies_test.rb | 18 ++++++++++++++++++ 5 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 activesupport/test/dependencies/mutual_one.rb create mode 100644 activesupport/test/dependencies/mutual_two.rb diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index be44f61ea7..bce5855c4a 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -45,18 +45,26 @@ module Dependencies #:nodoc: # Append .rb if we have a bare file name. load_file_name = (file_name =~ /\.rb$/ ? file_name : "#{file_name}.rb") - # Enable warnings iff this file has not been loaded before. - if history.include?(file_name) - load load_file_name - else - enable_warnings { load load_file_name } + # Record that we've seen this file *before* loading it to avoid an + # infinite loop with mutual dependencies. + loaded << file_name + + begin + # Enable warnings iff this file has not been loaded before. + if history.include?(file_name) + load load_file_name + else + enable_warnings { load load_file_name } + end + rescue + loaded.delete file_name + raise end else require file_name end - # Record that we've seen this file. - loaded << file_name + # Record history *after* loading so first load gets warnings. history << file_name end diff --git a/activesupport/test/dependencies/mutual_one.rb b/activesupport/test/dependencies/mutual_one.rb new file mode 100644 index 0000000000..eb5e056efb --- /dev/null +++ b/activesupport/test/dependencies/mutual_one.rb @@ -0,0 +1,2 @@ +$mutual_dependencies_count += 1 +require_dependency 'mutual_two' diff --git a/activesupport/test/dependencies/mutual_two.rb b/activesupport/test/dependencies/mutual_two.rb new file mode 100644 index 0000000000..99ba337e55 --- /dev/null +++ b/activesupport/test/dependencies/mutual_two.rb @@ -0,0 +1,2 @@ +$mutual_dependencies_count += 1 +require_dependency 'mutual_one' diff --git a/activesupport/test/dependencies/raises_exception.rb b/activesupport/test/dependencies/raises_exception.rb index df8d8b79d0..69750eee72 100644 --- a/activesupport/test/dependencies/raises_exception.rb +++ b/activesupport/test/dependencies/raises_exception.rb @@ -1,2 +1,3 @@ $raises_exception_load_count += 1 raise 'Loading me failed, so do not add to loaded or history.' +$raises_exception_load_count += 1 diff --git a/activesupport/test/dependencies_test.rb b/activesupport/test/dependencies_test.rb index a59b0284a9..b801ce6cf0 100644 --- a/activesupport/test/dependencies_test.rb +++ b/activesupport/test/dependencies_test.rb @@ -79,4 +79,22 @@ class DependenciesTest < Test::Unit::TestCase ensure Dependencies.mechanism = old_mechanism end + + def test_mutual_dependencies_dont_infinite_loop + $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/dependencies" + old_mechanism, Dependencies.mechanism = Dependencies.mechanism, :load + + $mutual_dependencies_count = 0 + assert_nothing_raised { require_dependency 'mutual_one' } + assert_equal 2, $mutual_dependencies_count + + Dependencies.clear + + $mutual_dependencies_count = 0 + assert_nothing_raised { require_dependency 'mutual_two' } + assert_equal 2, $mutual_dependencies_count + ensure + $LOAD_PATH.shift + Dependencies.mechanism = old_mechanism + end end -- cgit v1.2.3