Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

constant_watch_stack must be protected by a mutex

#1816

For http://jira.codehaus.org/browse/... I investigated what looked like an Array being concurrently modified by multiple threads. The backtrace led me to active_support/dependencies.rb and the constant_watch_stack. This stack is an array updated during requires. Concurrent requires can cause the array to become corrupted under parallel Ruby implementations like JRuby.

The user provided the following script to reproduce it. It's not consistent, but with enough runs it does fail under JRuby:


require 'rubygems'
require 'active_record'
require 'thread'
require 'rexml/encoding'

#This will ensure activesupport will override Kernel.require
class MyTable < ActiveRecord::Base
  set_table_name "table"
end


#build a test case with enough iterations to reproduce the problem.
#Since it's a race condition it'll occur randomly throughout the test
#
#if you can't reproduce the problem on your computer, try to increase the number of iterations
th = []
100.times do
  th << Thread.new {
    #this is what REXML is doing in $ruby_home/lib/ruby/1.8/rexml/encoding.rb (line 48)
    require 'rexml/encodings/UTF-8.rb' #active_support will try to load the file
  }
end
th.each do |t|
  t.join
end

I whipped together a patch that adds a mutex alongside constant_watch_stack and uses it to synchronize all mutations and iterations over the stack. The patch is at http://gist.github.com/54401 and is against rails master@e6493eb9b76de73afef2706493efd090dfff4ecc.

Feel free to contact me with questions.

Reported by Charles Oliver Nutter · January 29th, 2009 @ 06:14 AM

State: committed
Milestone: 2.x
Assigned to: Jeremy Kemper Jeremy Kemper
Importance: none

Activity

  1. Charles Oliver Nutter
    Charles Oliver Nutter

    I confirmed the provided script fails on unpatched activesupport and succeeds (or at least succeeds for about an hour of my testing) on a patched activesupport. I used the following command line:

    
    jruby -e "10000.times { system 'jruby test.rb' or fail }"
    

    January 29th, 2009 @ 06:27 AM

  2. Charles Oliver Nutter
    Charles Oliver Nutter

    Ahh, contributor guides are nice. Re-attaching patch as format-patch.

    January 29th, 2009 @ 06:34 AM

  3. Pratik
    Pratik
    • Assigned user set to Jeremy Kemper

    January 30th, 2009 @ 03:35 PM

  4. Repository
    Repository
    • State changed from new to committed

    (from [ed0e5640879fd42c00fc5900e0355a0ea1dcf2ad]) Ensure constant_watch_stack is protected by a mutex, so concurrent requires do not corrupt it.

    [#1816 constant_watch_stack must be protected by a mutex state:committed]

    Signed-off-by: Jeremy Kemper jeremy@bitsweat.net http://github.com/rails/rails/co...

    January 30th, 2009 @ 04:27 PM