Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Restore concurrent requires

When #8374 was fixed all requires were serialized, so one thread would
be blocked waiting for gem resolution (if any) and require in another
thread.  This is undesirable for JRuby, in particular.

The monitor protecting the RubyGems internals only needs to cover gem
activation and modifying $LOAD_PATH, not requiring files.

Now the monitor is released before calling the original Kernel#require
which allows other threads to require files without waiting for
RubyGems.

Fixes #640

See also #637
  • Loading branch information...
commit 16fc8e8b90830644cf5eed6b71c7ec2dac4ec5fc 1 parent 8993b5f
Eric Hodel drbrain authored
Showing with 31 additions and 4 deletions.
  1. +7 −0 History.txt
  2. +24 −4 lib/rubygems/core_ext/kernel_require.rb
7 History.txt
View
@@ -1,5 +1,12 @@
# coding: UTF-8
+=== 2.1.2
+
+Bug fixes:
+
+* Restore concurrent requires following the fix for ruby bug #8374. Pull
+ request #637 and issue #640 by Charles Nutter.
+
=== 2.1.1 / 2013-09-10
Bug fixes:
28 lib/rubygems/core_ext/kernel_require.rb
View
@@ -48,7 +48,12 @@ def require path
# normal require handle loading a gem from the rescue below.
if Gem::Specification.unresolved_deps.empty? then
- return gem_original_require(path)
+ begin
+ RUBYGEMS_ACTIVATION_MONITOR.exit
+ return gem_original_require(path)
+ ensure
+ RUBYGEMS_ACTIVATION_MONITOR.enter
+ end
end
# If +path+ is for a gem that has already been loaded, don't
@@ -61,7 +66,12 @@ def require path
s.activated? and s.contains_requirable_file? path
}
- return gem_original_require(path) if spec
+ begin
+ RUBYGEMS_ACTIVATION_MONITOR.exit
+ return gem_original_require(path)
+ ensure
+ RUBYGEMS_ACTIVATION_MONITOR.enter
+ end if spec
# Attempt to find +path+ in any unresolved gems...
@@ -109,11 +119,21 @@ def require path
valid.activate
end
- gem_original_require path
+ begin
+ RUBYGEMS_ACTIVATION_MONITOR.exit
+ return gem_original_require(path)
+ ensure
+ RUBYGEMS_ACTIVATION_MONITOR.enter
+ end
rescue LoadError => load_error
if load_error.message.start_with?("Could not find") or
(load_error.message.end_with?(path) and Gem.try_activate(path)) then
- return gem_original_require(path)
+ begin
+ RUBYGEMS_ACTIVATION_MONITOR.exit
+ return gem_original_require(path)
+ ensure
+ RUBYGEMS_ACTIVATION_MONITOR.enter
+ end
end
raise load_error
Please sign in to comment.
Something went wrong with that request. Please try again.