Yes, this modification was only written for 1.0 branch, because I had the impression that Bill Dortch would do something on the trunk anyway. However, it is easy to apply to trunk as well, I suspect. I will have a look tomorrow.

This modification merely solves (as solvable as I possible can do without refactoring) concurrent access to the method hash map. I do not have much knowledge on the domain models you use, so I focused entirely on the specified map. I followed the source code to find all places in which the map was exposed directly or indirectly, and analyzed it for race conditions. I then ran the test cases with a code coverage tool to evaluate the usage pattern, before I decided on the solution.

During analysis I did found some bad smells..
a) internal collections are made publicly available (without any description or restrictions in javadoc about semantics) b) The collection is iterated at caller, when behaviour should be at callee. (Class-Responsibility)

So even if I supplied a fix, there are still refactoring which could be done. However, I would rather wait a while until I understand the domain model better.

Is there any documentation on the jruby architecture? For the core, at least?

Regards,
/Niels

Charles Oliver Nutter (JIRA) skrev:
[ http://jira.codehaus.org/browse/JRUBY-1259?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_112225 ]
Charles Oliver Nutter commented on JRUBY-1259:
----------------------------------------------

So is this only a modification to 1.0 branch? I'd actually like to see a better 
method hash on trunk as well, since MethodCache is being voted out and the 
original global method cache is just a hash too.

Method access is not threadsafe
-------------------------------

                Key: JRUBY-1259
                URL: http://jira.codehaus.org/browse/JRUBY-1259
            Project: JRuby
         Issue Type: Bug
         Components: Core Classes/Modules
           Reporter: Bill Dortch
           Priority: Critical
        Attachments: patch-max.txt


Method access (add/remove/search) in JRuby is currently not threadsafe.
I've just made a couple of changes to MethodCache that should help, though I'm 
still not convinced that it is safe to use without synchronization. (My changes 
are intended to address atomicity issues, but as reported elsewhere, JIT 
behavior in sequencing operations may lead to problems if synchronization is 
not done properly, or, in this case, at all.)
There are also a number of places that the _methods_ HashMap in RubyModule is 
accessed unsafely. This is easy enough to demonstrate:
{code}
class C; end
t1 = Thread.new do
loop do
  class C
    def a; end
    def b; end
    def c; end
    def d; end
  end
end
end
t2 = Thread.new do
loop do
  C.send :remove_method, :a rescue nil
  C.send :remove_method, :b rescue nil
  C.send :remove_method, :c rescue nil
  C.send :remove_method, :d rescue nil
end
end
loop do
  C.instance_methods
  C.instance_methods
  C.instance_methods
  C.instance_methods
end
{code}
Wait for a moment, and you'll get:
{noformat}
NativeException: java.util.ConcurrentModificationException: null
        from HashMap.java:793:in `java.util.HashMap$HashIterator.nextEntry'
        from HashMap.java:833:in `java.util.HashMap$EntryIterator.next'
        from HashMap.java:831:in `java.util.HashMap$EntryIterator.next'
        from RubyModule.java:1597:in `org.jruby.RubyModule.instance_methods'
        from RubyModule.java:1624:in `org.jruby.RubyModule.instance_methods'
etc...
{noformat}
This is a fairly benign outcome, a stack trace spewn across one's screen being 
a pretty clear indication that something has gone amiss.  But there are other 
access points where more subtle, possibly undetected (or misinterpreted) 
problems might arise.  I suspect, for example, that JRUBY-1251 is one of these 
(though it may be resolved by my MethodCache fix.)
It would be easy enough just to add synchronization where it's currently 
missing, but I'm working on a MethodMap class (part of my refactoring 
experiment in the bdortch/bnw branch) that will provide a more performant 
solution.  I'll try to get that piece into trunk sooner rather than later.
-Bill



---------------------------------------------------------------------
To unsubscribe from this list please visit:

   http://xircles.codehaus.org/manage_email

Reply via email to