Bug #7530

Concurrent loads fail with mutex errors

Added by Charles Nutter over 1 year ago. Updated over 1 year ago.

[ruby-core:50645]
Status:Closed
Priority:High
Assignee:Masaki Matsushita
Category:core
Target version:2.0.0
ruby -v:ruby 2.0.0dev (2012-12-01 trunk 38126) [x86_64-darwin11.4.2] Backport:

Description

I have no idea what's going on here.

jruby-1.7.0 ~/projects/vts-jruby $ cat benchloadpath.rb
require 'benchmark'

FAKEPATHS = ARGV[0].toi || 100
THREADS = 8
ITERATIONSPERTHREAD = 1000

FAKE_PATHS.times do |i|
$:.unshift "foo#{i}"
end

$: << '.'

system 'touch loadpathbench_script.rb'
puts Benchmark.measure {
@threads = THREADS.times.map do
Thread.new {
ITERATIONSPERTHREAD.times do
require 'loadpathbench_script'
$".pop
end
}
end
@threads.each { |t| t.join }
}
system 'rm loadpathbench_script.rb'

jruby-1.7.0 ~/projects/vts-jruby $ ruby-2.0.0 -rubygems benchloadpath.rb 100
/usr/local/lib/ruby/2.0.0/rubygems/customrequire.rb:36:in require': wrong argument type false (expected mutex) (TypeError)
from /usr/local/lib/ruby/2.0.0/rubygems/custom_require.rb:36:in
require'
from bench
loadpath.rb:18:in block (4 levels) in <main>'
from bench_load_path.rb:17:in
times'
from bench
load_path.rb:17:in `block (3 levels) in '

jruby-1.7.0 ~/projects/vts-jruby $ ruby-2.0.0 --disable-gems benchloadpath.rb 100
benchloadpath.rb:18:in require': wrong argument type false (expected mutex) (TypeError)
from bench_load_path.rb:18:in
block (4 levels) in '
from benchloadpath.rb:17:in times'
from bench_load_path.rb:17:in
block (3 levels) in '

With verbose on, I get this error and a bunch of circular require warnings, even though I'm not doing any circular requires here.

ruby-2.0.0-preview2 ~/projects/vts-jruby $ ruby -v benchloadpath.rb
ruby 2.0.0dev (2012-12-01 trunk 38126) [x8664-darwin11.4.2]
/Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site
ruby/2.0.0/rubygems/customrequire.rb:36: warning: loading in progress, circular require considered harmful - /Users/headius/projects/vts-jruby/loadpathbenchscript.rb
from benchloadpath.rb:17:in block (3 levels) in <main>'
from bench_load_path.rb:17:in
times'
from benchloadpath.rb:18:in block (4 levels) in <main>'
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site_ruby/2.0.0/rubygems/custom_require.rb:36:in
require'
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/siteruby/2.0.0/rubygems/customrequire.rb:36:in require'
/Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site_ruby/2.0.0/rubygems/custom_require.rb:36: warning: loading in progress, circular require considered harmful - /Users/headius/projects/vts-jruby/__load_path_bench_script__.rb
from bench_load_path.rb:17:in
block (3 levels) in '
from benchloadpath.rb:17:in times'
from bench_load_path.rb:18:in
block (4 levels) in '
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/siteruby/2.0.0/rubygems/customrequire.rb:36:in require'
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site_ruby/2.0.0/rubygems/custom_require.rb:36:in
require'
/Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/siteruby/2.0.0/rubygems/customrequire.rb:36: warning: loading in progress, circular require considered harmful - /Users/headius/projects/vts-jruby/
loadpathbenchscript.rb
from bench
loadpath.rb:17:in block (3 levels) in <main>'
from bench_load_path.rb:17:in
times'
from bench
loadpath.rb:18:in block (4 levels) in <main>'
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site_ruby/2.0.0/rubygems/custom_require.rb:36:in
require'
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site
ruby/2.0.0/rubygems/customrequire.rb:36:in require'
/Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site_ruby/2.0.0/rubygems/custom_require.rb:36: warning: loading in progress, circular require considered harmful - /Users/headius/projects/vts-jruby/__load_path_bench_script__.rb
from bench_load_path.rb:17:in
block (3 levels) in '
from bench
loadpath.rb:17:in times'
from bench_load_path.rb:18:in
block (4 levels) in '
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site
ruby/2.0.0/rubygems/customrequire.rb:36:in require'
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site_ruby/2.0.0/rubygems/custom_require.rb:36:in
require'
/Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site
ruby/2.0.0/rubygems/customrequire.rb:36: warning: loading in progress, circular require considered harmful - /Users/headius/projects/vts-jruby/loadpathbenchscript.rb
from benchloadpath.rb:17:in block (3 levels) in <main>'
from bench_load_path.rb:17:in
times'
from benchloadpath.rb:18:in block (4 levels) in <main>'
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site_ruby/2.0.0/rubygems/custom_require.rb:36:in
require'
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/siteruby/2.0.0/rubygems/customrequire.rb:36:in require'
/Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site_ruby/2.0.0/rubygems/custom_require.rb:36: warning: loading in progress, circular require considered harmful - /Users/headius/projects/vts-jruby/__load_path_bench_script__.rb
from bench_load_path.rb:17:in
block (3 levels) in '
from benchloadpath.rb:17:in times'
from bench_load_path.rb:18:in
block (4 levels) in '
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/siteruby/2.0.0/rubygems/customrequire.rb:36:in require'
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site_ruby/2.0.0/rubygems/custom_require.rb:36:in
require'
/Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/siteruby/2.0.0/rubygems/customrequire.rb:36: warning: loading in progress, circular require considered harmful - /Users/headius/projects/vts-jruby/
loadpathbenchscript.rb
from bench
loadpath.rb:17:in block (3 levels) in <main>'
from bench_load_path.rb:17:in
times'
from bench
loadpath.rb:18:in block (4 levels) in <main>'
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site_ruby/2.0.0/rubygems/custom_require.rb:36:in
require'
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site
ruby/2.0.0/rubygems/customrequire.rb:36:in require'
/Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site_ruby/2.0.0/rubygems/custom_require.rb:36: warning: loading in progress, circular require considered harmful - /Users/headius/projects/vts-jruby/__load_path_bench_script__.rb
from bench_load_path.rb:17:in
block (3 levels) in '
from bench
loadpath.rb:17:in times'
from bench_load_path.rb:18:in
block (4 levels) in '
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site
ruby/2.0.0/rubygems/customrequire.rb:36:in require'
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site_ruby/2.0.0/rubygems/custom_require.rb:36:in
require'
/Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site
ruby/2.0.0/rubygems/customrequire.rb:36: warning: loading in progress, circular require considered harmful - /Users/headius/projects/vts-jruby/loadpathbenchscript_.rb
from bench
loadpath.rb:17:in block (3 levels) in <main>'
from bench_load_path.rb:17:in
times'
from bench
loadpath.rb:18:in block (4 levels) in <main>'
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site_ruby/2.0.0/rubygems/custom_require.rb:36:in
require'
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site
ruby/2.0.0/rubygems/customrequire.rb:36:in require'
/Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site_ruby/2.0.0/rubygems/custom_require.rb:36: warning: loading in progress, circular require considered harmful - /Users/headius/projects/vts-jruby/__load_path_bench_script__.rb
from bench_load_path.rb:17:in
block (3 levels) in '
from bench
loadpath.rb:17:in times'
from bench_load_path.rb:18:in
block (4 levels) in '
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site
ruby/2.0.0/rubygems/customrequire.rb:36:in require'
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site_ruby/2.0.0/rubygems/custom_require.rb:36:in
require'
/Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site
ruby/2.0.0/rubygems/customrequire.rb:36:in require': Attempt to unlock a mutex which is locked by another thread (ThreadError)
from /Users/headius/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/site_ruby/2.0.0/rubygems/custom_require.rb:36:in
require'
from bench
loadpath.rb:18:in block (4 levels) in <main>'
from bench_load_path.rb:17:in
times'
from bench
load_path.rb:17:in `block (3 levels) in '

Associated revisions

Revision 38744
Added by glass over 1 year ago

  • load.c (load_lock): fix not to delete thread shield twice.
    it may break the shield locked by another thread.
    [Bug #7530]

  • test/ruby/test_require.rb: a test for above.

Revision 38750
Added by glass over 1 year ago

  • load.c (loadlock): if thread shield is destroyed and there is no waiting thread, insert new thread shield into loadtable. [Bug #7530]

History

#1 Updated by Usaku NAKAMURA over 1 year ago

  • Category set to core
  • Status changed from Open to Assigned
  • Assignee set to Motohiro KOSAKI
  • Target version set to 2.0.0

#2 Updated by Motohiro KOSAKI over 1 year ago

  • Assignee changed from Motohiro KOSAKI to Nobuyoshi Nakada

When removing $".pop likes following, this issue never happen.
So, I suspect this is require and threadshield issue.


require 'benchmark'

FAKEPATHS = ARGV[0].toi || 100
THREADS = 2
ITERATIONSPERTHREAD = 1000

FAKE_PATHS.times do |i|
$:.unshift "foo#{i}"
end

$: << '.'

ITERATIONSPERTHREAD.times {|i|
system "touch loadpathbench_script#{i}.rb"
}

puts Benchmark.measure {
@threads = THREADS.times.map do
Thread.new {
ITERATIONSPERTHREAD.times do |i|
require "loadpathbench_script#{i}"
end
}
end
@threads.each { |t| t.join }
}

ITERATIONSPERTHREAD.times {|i|
system "rm loadpathbench_script#{i}.rb"
}

#3 Updated by Nobuyoshi Nakada over 1 year ago

  • Priority changed from Normal to High

#4 Updated by Masaki Matsushita over 1 year ago

Here is the minimal code:

THREADS = 2
ITERATIONSPERTHREAD = 1000

system 'touch loadpathbench_script.rb'
THREADS.times.map {
Thread.new do
ITERATIONSPERTHREAD.times do
requirerelative 'loadpathbenchscript'
$".pop
end
end
}.each(&:join)
system 'rm _loadpathbenchscript
.rb'

#5 Updated by Masaki Matsushita over 1 year ago

  • Assignee changed from Nobuyoshi Nakada to Masaki Matsushita

#6 Updated by Anonymous over 1 year ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r38744.
Charles, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • load.c (load_lock): fix not to delete thread shield twice.
    it may break the shield locked by another thread.
    [Bug #7530]

  • test/ruby/test_require.rb: a test for above.

Also available in: Atom PDF