Posted by
rhatcher on
Aug 14, 2012; 7:01pm
URL: https://forum.jogamp.org/AWT-JOGL-Deadlock-Revisited-tp4025772p4025803.html
> Your jstack shows:
>
> "AWT-EventQueue-0" prio=10 tid=0xa668e800 nid=0x5f7e runnable [0xa635c000]
> java.lang.Thread.State: RUNNABLE
> at java.lang.StringBuilder.append(StringBuilder.java:132)
> at java.lang.Object.toString(Object.java:237)
> at java.lang.String.valueOf(String.java:2902)
>
> .. so for some reason it produces a String for-ever it seems like ?
Even though everything in the UI has stalled, thread AWT-EventQueue-0 does not appear to be stuck - or at least not totally stuck. It just happened to be at that spot at the time I ran jstack. I can resume the JVM in the debugger then suspend it again and AWT-EventQueue-0 will sometimes stop with a different stack trace. The stack trace in the previous jstack output is rooted in a logging statement in java.awt.EventDispatchThread.addEventFilter:
eventLog.finest("adding the event filter: " + filter);
The String creation is a side effect of "filter" being converted to String form, and ultimately leads to the default Object toString() method. It looks harmless on the surface.
> Minor note: Looks like you override AnimatorBase.display() w/ your
> DisplaySetAnimator.display().
This is a remnant from our previous code base that was based on 1.1.1a. There are some things that happen before and after super.display(). I commented out this overridden display() method and got the same behavior.
> We would need a small unit test to reproduce the issue of yours
> and to see whether it's JOGL who causes this 'overload'.
> IMHO .. it's not.
I would want the same thing. Not sure if I'll be able to reproduce it on a small scale, but I'll see what I can do.
I will be the first to admit that this problem almost certainly is something in our code base that 1.1.1a was more forgiving of. The main reason I'm consulting the forum is to get some thoughts from people who know a lot more about the internals of AWT event dispatching than I do (and to hopefully increase the chances that I won't have to discard a week of work and go back to using 1.1.1a, which would get us nowhere :-/ ).
Any time this hang happens I can always find a timer thread stuck at the lock.wait() call in java.awt.EventQueue's invokeAndWait method:
synchronized (lock) {
Toolkit.getEventQueue().postEvent(event);
while (!event.isDispatched()) {
lock.wait();
}
}
That spot - and the entire stack trace for that particular timer thread - is not unusual per se. On any random suspension of an app that's working ok this thread is likely to stop at this spot. However, when these hangs happen the debugger shows that the "while" loop is never exiting, which obviously suggests that wait() never returns and/or isDispatched() never returns true.
The event is an InvocationEvent. Looking at InvocationEvent's dispatch() method it looks like the most likely causes of being stuck in the "while" loop above would be that either the event's dispatch() method is never called, or dispatch() is called but the runnable's run() method is never completing. In either case the lock/notifier's notifyAll() would not be called and the InvocationEvent would never be marked as dispatched.
In this case the runnable appears to be "displayOnEDTAction" from GLCanvas. The first few lines of this runnable look like this.
private final Runnable displayOnEDTAction = new Runnable() {
@Override
public void run() {
final RecursiveLock _lock = lock;
_lock.lock();
try {
if( validateGLDrawable() ) {
helper.invokeGL(drawable, context, displayAction, initAction);
Maybe Eclipse's debugger is misleading me, but I can't find this runnable on any backtrace in the total set of threads, so I'm not sure if it's still waiting to run, is running and stuck, or has already completed. The lock appears to have a relatively short timeout on it so I would think if it ran at all it would complete at some point.
I added -Djogl.debug=true to the JVM args and re-ran this a few times. I've uploaded that output
here in case it might reveal something to a more informed eye. Note that I added an annotation in there to show where the output stops in the cases where the app hangs.
I'm continuing to pound of this of course, but if anybody has any further suggestions I'd like to hear them.