History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: JRUBY-2270
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Bill Dortch
Reporter: Peter K Chan
Votes: 0
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
JRuby

Deadlock With ReentrantLock and Java Integration

Created: 14/Mar/08 02:03 AM   Updated: 23/Apr/08 09:58 AM
Component/s: Java Integration
Affects Version/s: JRuby 1.1RC2
Fix Version/s: JRuby 1.1.1

Time Tracking:
Not Specified

Environment: Java 6


 Description  « Hide
When I run my multithreaded app using JRuby 1.1 RC2, deadlock results.

I am not sure about what happens, but my app uses ReentrantLock. My guess is that there is some synchronization done around JavaClass$InstanceMethodInvoker, which deadlocks when one thread holds the JavaClass$InstanceMethodInvoker and tries to acquire lock (using Java Integration) on a target ReentrantLock, while that target lock is being held by another thread that is looking to lock on to JavaClass$InstanceMethodInvoker (probably to call other Java methods before unlocking the target lock).

The following output from JConsole's deadlock tab provides a snapshot of the deadlock in action:

=== Thread "main" ===
Name: main
State: WAITING on java.util.concurrent.locks.ReentrantLock$NonfairSync@70f958 owned by: Tasker
Total blocked: 52,224 Total waited: 231

Stack trace:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:712)
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:743)
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1079)
java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:186)
java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
sun.reflect.GeneratedMethodAccessor33.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.jruby.javasupport.JavaMethod.invokeWithExceptionHandling(JavaMethod.java:208)
org.jruby.javasupport.JavaMethod.invoke(JavaMethod.java:184)
org.jruby.javasupport.JavaClass$InstanceMethodInvoker.execute(JavaClass.java:406)
— locked org.jruby.javasupport.JavaClass$InstanceMethodInvoker@2d2309
org.jruby.internal.runtime.methods.SimpleCallbackMethod.call(SimpleCallbackMethod.java:67)
org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:298)
org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
org.jruby.runtime.CallSite$InlineCachingCallSite.cacheAndCall(CallSite.java:166)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:301)
(snip)

=== Thread "Tasker" ===
Name: Tasker
State: BLOCKED on org.jruby.javasupport.JavaClass$InstanceMethodInvoker@2d2309 owned by: main
Total blocked: 1 Total waited: 2

Stack trace:
org.jruby.javasupport.JavaClass$InstanceMethodInvoker.execute(JavaClass.java:384)
org.jruby.internal.runtime.methods.SimpleCallbackMethod.call(SimpleCallbackMethod.java:67)
org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:298)
org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:298)
org.jruby.evaluator.ASTInterpreter.fCallNode(ASTInterpreter.java:1100)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:354)
org.jruby.evaluator.ASTInterpreter.localAsgnNode(ASTInterpreter.java:1256)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:387)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
(snip)



 All   Comments   Work Log   Change History      Sort Order: Ascending order - Click to sort in descending order
Peter K Chan - 20/Mar/08 09:58 PM
My attempt to create a simple test case based on my postulation above has so far failed to reproduce the deadlock. However, I tested out my app with RC3 and the deadlock still happens reliably.

My app did not have this deadlocking problem running under JRuby 1.0 final.


Peter K Chan - 20/Mar/08 10:01 PM
Here are the stacktraces from JConsole's deadlock tab of the two deadlocked threads:

=== Thread CPU1 ===
Name: CPU1
State: BLOCKED on org.jruby.javasupport.JavaClass$InstanceMethodInvoker@1124805 owned by: CPU0
Total blocked: 6 Total waited: 0

Stack trace:
org.jruby.javasupport.JavaClass$InstanceMethodInvoker.execute(JavaClass.java:389)
org.jruby.internal.runtime.methods.SimpleCallbackMethod.call(SimpleCallbackMethod.java:67)
org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:240)
org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.ensureNode(ASTInterpreter.java:1072)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:348)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:240)
org.jruby.evaluator.ASTInterpreter.fCallNode(ASTInterpreter.java:1100)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:354)
org.jruby.evaluator.ASTInterpreter.localAsgnNode(ASTInterpreter.java:1256)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:387)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
org.jruby.runtime.CallSite$InlineCachingCallSite.cacheAndCall(CallSite.java:102)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:243)
org.jruby.evaluator.ASTInterpreter.fCallNode(ASTInterpreter.java:1100)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:354)
org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:648)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
org.jruby.runtime.CallSite$InlineCachingCallSite.cacheAndCall(CallSite.java:102)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:243)
org.jruby.evaluator.ASTInterpreter.fCallNode(ASTInterpreter.java:1100)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:354)
org.jruby.evaluator.ASTInterpreter.orNode(ASTInterpreter.java:1455)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:439)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
org.jruby.RubyClass.invoke(RubyClass.java:236)
org.jruby.javasupport.util.RuntimeHelpers.invoke(RuntimeHelpers.java:314)
org.jruby.RubyObject.callMethod(RubyObject.java:475)
org.jruby.javasupport.util.RuntimeHelpers.callMethodMissing(RuntimeHelpers.java:297)
org.jruby.runtime.CallSite$InlineCachingCallSite.cacheAndCall(CallSite.java:94)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:243)
org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.runtime.InterpretedBlock.yield(InterpretedBlock.java:150)
org.jruby.runtime.Block.yield(Block.java:114)
org.jruby.evaluator.ASTInterpreter.yieldNode(ASTInterpreter.java:1817)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:493)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.rescueNode(ASTInterpreter.java:1517)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:452)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.ensureNode(ASTInterpreter.java:1072)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:348)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:253)
org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:662)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
org.jruby.evaluator.ASTInterpreter.localAsgnNode(ASTInterpreter.java:1256)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:387)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.rescueNode(ASTInterpreter.java:1517)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:452)
org.jruby.evaluator.ASTInterpreter.ensureNode(ASTInterpreter.java:1072)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:348)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
org.jruby.RubyClass.invoke(RubyClass.java:236)
org.jruby.javasupport.util.RuntimeHelpers.invokeAs(RuntimeHelpers.java:322)
org.jruby.RubyObject.callSuper(RubyObject.java:462)
org.jruby.javasupport.util.RuntimeHelpers.callZSuper(RuntimeHelpers.java:564)
org.jruby.evaluator.ASTInterpreter.zsuperNode(ASTInterpreter.java:1826)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:497)
org.jruby.evaluator.ASTInterpreter.localAsgnNode(ASTInterpreter.java:1256)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:387)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.runtime.InterpretedBlock.yield(InterpretedBlock.java:150)
org.jruby.runtime.Block.yield(Block.java:114)
org.jruby.evaluator.ASTInterpreter.yieldNode(ASTInterpreter.java:1817)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:493)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
org.jruby.runtime.CallSite$InlineCachingCallSite.cacheAndCall(CallSite.java:87)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:256)
org.jruby.evaluator.ASTInterpreter.fCallNode(ASTInterpreter.java:1105)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:354)
org.jruby.evaluator.ASTInterpreter.setupArgs(ASTInterpreter.java:2155)
org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:649)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.ensureNode(ASTInterpreter.java:1072)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:348)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
org.jruby.runtime.CallSite$InlineCachingCallSite.cacheAndCall(CallSite.java:87)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:256)
org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:662)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
org.jruby.runtime.CallSite$InlineCachingCallSite.cacheAndCall(CallSite.java:102)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:243)
org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
org.jruby.evaluator.ASTInterpreter.setupArgs(ASTInterpreter.java:2155)
org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:649)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:371)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
org.jruby.RubyMethod.call(RubyMethod.java:110)
org.jruby.RubyMethodInvoker$call_method_0_0.call(Unknown Source)
org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
org.jruby.runtime.CallSite$InlineCachingCallSite.cacheAndCall(CallSite.java:102)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:243)
org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
org.jruby.evaluator.ASTInterpreter.localAsgnNode(ASTInterpreter.java:1256)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:387)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.runtime.InterpretedBlock.yield(InterpretedBlock.java:150)
org.jruby.runtime.Block.yield(Block.java:114)
org.jruby.evaluator.ASTInterpreter.yieldNode(ASTInterpreter.java:1817)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:493)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
org.jruby.runtime.CallSite$InlineCachingCallSite.cacheAndCall(CallSite.java:87)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:256)
org.jruby.evaluator.ASTInterpreter.fCallNode(ASTInterpreter.java:1105)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:354)
org.jruby.evaluator.ASTInterpreter.localAsgnNode(ASTInterpreter.java:1256)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:387)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.rescueNode(ASTInterpreter.java:1517)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:452)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.ensureNode(ASTInterpreter.java:1072)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:348)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
org.jruby.runtime.CallSite$InlineCachingCallSite.cacheAndCall(CallSite.java:102)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:243)
org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:371)
org.jruby.evaluator.ASTInterpreter.whileNode(ASTInterpreter.java:1761)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:489)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.runtime.InterpretedBlock.yield(InterpretedBlock.java:150)
org.jruby.runtime.InterpretedBlock.call(InterpretedBlock.java:103)
org.jruby.runtime.Block.call(Block.java:105)
org.jruby.RubyProc.call(RubyProc.java:203)
org.jruby.RubyProc.call(RubyProc.java:188)
org.jruby.RubyProcInvoker$call_method_0_0.call(Unknown Source)
org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:240)
org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
org.jruby.evaluator.ASTInterpreter.rescueNode(ASTInterpreter.java:1517)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:452)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.runtime.InterpretedBlock.yield(InterpretedBlock.java:150)
org.jruby.runtime.Block.yield(Block.java:114)
org.jruby.evaluator.ASTInterpreter.yieldNode(ASTInterpreter.java:1817)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:493)
org.jruby.evaluator.ASTInterpreter.ensureNode(ASTInterpreter.java:1072)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:348)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
org.jruby.runtime.CallSite$InlineCachingCallSite.cacheAndCall(CallSite.java:87)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:256)
org.jruby.evaluator.ASTInterpreter.fCallNode(ASTInterpreter.java:1105)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:354)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.whileNode(ASTInterpreter.java:1761)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:489)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.runtime.InterpretedBlock.yield(InterpretedBlock.java:150)
org.jruby.runtime.InterpretedBlock.call(InterpretedBlock.java:103)
org.jruby.runtime.Block.call(Block.java:105)
org.jruby.RubyProc.call(RubyProc.java:203)
org.jruby.RubyProc.call(RubyProc.java:188)
org.jruby.RubyProcInvoker$call_method_0_0.call(Unknown Source)
org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:240)
org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
org.jruby.runtime.InterpretedBlock.yield(InterpretedBlock.java:150)
org.jruby.runtime.InterpretedBlock.call(InterpretedBlock.java:103)
org.jruby.runtime.Block.call(Block.java:105)
org.jruby.RubyProc.call(RubyProc.java:203)
org.jruby.RubyProc.call(RubyProc.java:182)
org.jruby.internal.runtime.RubyNativeThread.run(RubyNativeThread.java:72)

=== Thread CPU0 ===
Name: CPU0
State: WAITING on java.util.concurrent.locks.ReentrantLock$NonfairSync@11c5bb0 owned by: CPU1
Total blocked: 4 Total waited: 1

Stack trace:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:712)
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:743)
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1079)
java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:186)
java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.jruby.javasupport.JavaMethod.invokeWithExceptionHandling(JavaMethod.java:251)
org.jruby.javasupport.JavaMethod.invoke(JavaMethod.java:223)
org.jruby.javasupport.JavaClass$InstanceMethodInvoker.execute(JavaClass.java:411)

  • locked org.jruby.javasupport.JavaClass$InstanceMethodInvoker@1124805
    org.jruby.internal.runtime.methods.SimpleCallbackMethod.call(SimpleCallbackMethod.java:67)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
    org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:240)
    org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
    org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
    org.jruby.evaluator.ASTInterpreter.ensureNode(ASTInterpreter.java:1072)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:348)
    org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
    org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:240)
    org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
    org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:70)
    org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:272)
    org.jruby.evaluator.ASTInterpreter.vcallNode(ASTInterpreter.java:1748)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:484)
    org.jruby.evaluator.ASTInterpreter.instAsgnNode(ASTInterpreter.java:1236)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:381)
    org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
    org.jruby.evaluator.ASTInterpreter.rescueNode(ASTInterpreter.java:1517)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:452)
    org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:70)
    org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:272)
    org.jruby.evaluator.ASTInterpreter.vcallNode(ASTInterpreter.java:1748)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:484)
    org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
    org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
    org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:240)
    org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
    org.jruby.evaluator.ASTInterpreter.dAsgnNode(ASTInterpreter.java:858)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:328)
    org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
    org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
    org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
    org.jruby.runtime.InterpretedBlock.yield(InterpretedBlock.java:150)
    org.jruby.runtime.InterpretedBlock.call(InterpretedBlock.java:103)
    org.jruby.runtime.Block.call(Block.java:105)
    org.jruby.RubyProc.call(RubyProc.java:203)
    org.jruby.internal.runtime.methods.ProcMethod.call(ProcMethod.java:64)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
    org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:240)
    org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
    org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:648)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:371)
    org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
    org.jruby.RubyMethod.call(RubyMethod.java:110)
    org.jruby.RubyMethodInvoker$call_method_0_0.call(Unknown Source)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
    org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:240)
    org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
    org.jruby.evaluator.ASTInterpreter.localAsgnNode(ASTInterpreter.java:1256)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:387)
    org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
    org.jruby.runtime.InterpretedBlock.yield(InterpretedBlock.java:150)
    org.jruby.runtime.Block.yield(Block.java:114)
    org.jruby.evaluator.ASTInterpreter.yieldNode(ASTInterpreter.java:1817)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:493)
    org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
    org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
    org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:253)
    org.jruby.evaluator.ASTInterpreter.fCallNode(ASTInterpreter.java:1105)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:354)
    org.jruby.evaluator.ASTInterpreter.localAsgnNode(ASTInterpreter.java:1256)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:387)
    org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
    org.jruby.evaluator.ASTInterpreter.rescueNode(ASTInterpreter.java:1517)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:452)
    org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
    org.jruby.evaluator.ASTInterpreter.ensureNode(ASTInterpreter.java:1072)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:348)
    org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
    org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
    org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
    org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
    org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:240)
    org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:371)
    org.jruby.evaluator.ASTInterpreter.whileNode(ASTInterpreter.java:1761)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:489)
    org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
    org.jruby.runtime.InterpretedBlock.yield(InterpretedBlock.java:150)
    org.jruby.runtime.InterpretedBlock.call(InterpretedBlock.java:103)
    org.jruby.runtime.Block.call(Block.java:105)
    org.jruby.RubyProc.call(RubyProc.java:203)
    org.jruby.RubyProc.call(RubyProc.java:188)
    org.jruby.RubyProcInvoker$call_method_0_0.call(Unknown Source)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
    org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:240)
    org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
    org.jruby.evaluator.ASTInterpreter.rescueNode(ASTInterpreter.java:1517)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:452)
    org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
    org.jruby.runtime.InterpretedBlock.yield(InterpretedBlock.java:150)
    org.jruby.runtime.Block.yield(Block.java:114)
    org.jruby.evaluator.ASTInterpreter.yieldNode(ASTInterpreter.java:1817)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:493)
    org.jruby.evaluator.ASTInterpreter.ensureNode(ASTInterpreter.java:1072)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:348)
    org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
    org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:176)
    org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:253)
    org.jruby.evaluator.ASTInterpreter.fCallNode(ASTInterpreter.java:1105)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:354)
    org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
    org.jruby.evaluator.ASTInterpreter.whileNode(ASTInterpreter.java:1761)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:489)
    org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
    org.jruby.runtime.InterpretedBlock.yield(InterpretedBlock.java:150)
    org.jruby.runtime.InterpretedBlock.call(InterpretedBlock.java:103)
    org.jruby.runtime.Block.call(Block.java:105)
    org.jruby.RubyProc.call(RubyProc.java:203)
    org.jruby.RubyProc.call(RubyProc.java:188)
    org.jruby.RubyProcInvoker$call_method_0_0.call(Unknown Source)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:66)
    org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:240)
    org.jruby.evaluator.ASTInterpreter.callNode(ASTInterpreter.java:657)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:308)
    org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:631)
    org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:302)
    org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168)
    org.jruby.runtime.InterpretedBlock.yield(InterpretedBlock.java:150)
    org.jruby.runtime.InterpretedBlock.call(InterpretedBlock.java:103)
    org.jruby.runtime.Block.call(Block.java:105)
    org.jruby.RubyProc.call(RubyProc.java:203)
    org.jruby.RubyProc.call(RubyProc.java:182)
    org.jruby.internal.runtime.RubyNativeThread.run(RubyNativeThread.java:72)

Peter K Chan - 21/Mar/08 11:11 PM
I have drilled down further in a debugger, and it appears that the deadlock stems from org.jruby.javasupport.JavaClass$InstanceMethodInvoker.execute(...). This method is declare to be synchronized, and the deadlock results when one thread already holds lock on a ReentrantLock and attempts to enters this execute() method, but deadlocks because another thread has entered it and was trying to lock onto that ReentrantLock inside this synchronized method.

The two specific lines in org.jruby.javasupport.JavaClass$InstanceMethodInvoker.execute(...) that deadlock are:

synchronized public IRubyObject execute(IRubyObject self, IRubyObject[] args, Block block) {
createJavaMethods(self.getRuntime()); // Deadlocks entering the method, thread already holds ReentrantLock

and,

return Java.java_to_ruby(self,javaMethod.invoke(convertedArgs),Block.NULL_BLOCK); // Deadlocks here while calling "lock" on the ReentrantLock.

I do not know enough about the JRuby codebase to offer any patch or suggestion. However, I am able to consistently produce deadlock at the two locations above. Let me know if there is anything else that I can gather.


Bill Dortch - 22/Mar/08 06:03 PM
Fixed in r6315. Leaving open until verified. Peter C., please confirm that this fixes the problem for you. Thanks.

Peter K Chan - 23/Mar/08 12:46 AM
That fixed it. Thanks Bill!

Bill Dortch - 23/Mar/08 02:06 AM
Fix verified.

Charles Oliver Nutter - 26/Mar/08 12:57 PM
Migrating bugs marked as fixed in 1.1 after the RC3 release as 1.1.1, since they are not going to be promoted into the 1.1 release.