Bug 42268 - Deadlock when JSVGComponent.stopProcessing() invoked from Swing thread
Summary: Deadlock when JSVGComponent.stopProcessing() invoked from Swing thread
Status: NEW
Alias: None
Product: Batik - Now in Jira
Classification: Unclassified
Component: Bridge (show other bugs)
Version: 1.6
Hardware: All Linux
: P1 critical
Target Milestone: ---
Assignee: Batik Developer's Mailing list
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-04-26 11:36 UTC by Archie Cobbs
Modified: 2007-04-26 12:16 UTC (History)
0 users



Attachments
Patch to fix this bug (873 bytes, patch)
2007-04-26 12:16 UTC, Archie Cobbs
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Archie Cobbs 2007-04-26 11:36:10 UTC
Note: my version of 1.6 includes the fix to Bug #40681 (which is also checked
into SVN and part of 1.7). It may be that this bug was created/relvealed by the
patch that was applied to fix Bug #40681.

My Swing GUI locked up. CTRL-\ revealed a deadlock between the Swing thread and
the Batik updater thread:

Swing thread:

     [java] "AWT-EventQueue-0" prio=1 tid=0x083fec88 nid=0x79da waiting for
monitor entry [0x5cf64000..0x5cf65020]
     [java]     at org.apache.batik.bridge.UpdateManager.interrupt(Unknown Source)
     [java]     - waiting to lock <0x630f6c00> (a
org.apache.batik.util.RunnableQueue)
     [java]     - locked <0x630f9470> (a org.apache.batik.bridge.UpdateManager)
     [java]     at
org.apache.batik.swing.svg.JSVGComponent.stopProcessing(Unknown Source)
     [java]     at
com.awarix.trak.client.svg.SVGLoadManager$1.run(SVGLoadManager.java:328)
     [java]     at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
     [java]     at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
     [java]     at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
     [java]     at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
     [java]     at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
     [java]     at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
     [java]     at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)

Batik update manager thread:

     [java] "RunnableQueue-2" daemon prio=1 tid=0x5bda1810 nid=0x7a88 in
Object.wait() [0x5d47f000..0x5d480120]
     [java]     at java.lang.Object.wait(Native Method)
     [java]     - waiting on <0x61a2a490> (a java.awt.EventQueue$1AWTInvocationLock)
     [java]     at java.lang.Object.wait(Object.java:474)
     [java]     at java.awt.EventQueue.invokeAndWait(EventQueue.java:846)
     [java]     - locked <0x61a2a490> (a java.awt.EventQueue$1AWTInvocationLock)
     [java]     at
org.apache.batik.swing.svg.JSVGComponent$SVGListener.updateCompleted(Unknown Source)
     [java]     at org.apache.batik.bridge.UpdateManager$9.dispatch(Unknown Source)
     [java]     at org.apache.batik.util.EventDispatcher.dispatchEvent(Unknown
Source)
     [java]     at org.apache.batik.util.EventDispatcher.fireEvent(Unknown Source)
     [java]     at org.apache.batik.bridge.UpdateManager.fireEvent(Unknown Source)
     [java]     at org.apache.batik.bridge.UpdateManager.updateRendering(Unknown
Source)
     [java]     at org.apache.batik.bridge.UpdateManager.repaint(Unknown Source)
     [java]     at
org.apache.batik.bridge.UpdateManager$UpdateManagerRunHander.runnableInvoked(Unknown
Source)
     [java]     at org.apache.batik.util.RunnableQueue.runnableInvoked(Unknown
Source)
     [java]     - locked <0x630f6c00> (a org.apache.batik.util.RunnableQueue)
     [java]     at org.apache.batik.util.RunnableQueue.run(Unknown Source)
     [java]     at java.lang.Thread.run(Thread.java:595)

My code looks like this:

      SwingUtilities.invokeLater(new Runnable() {
          public void run() {
              canvas.stopProcessing();
              canvas.dispose();
          }
      });

The root of the problem seems to be that
JSVGComponent$SVGListener.updateCompleted() is calling invokeAndWait() instead
of invokeLater().

Not sure why this is necessary, but it in effect means that no code that runs in
the swing thread can ever try to lock the runnable queue or risk a deadlock!

If that's really the intent, then this needs to be documented. Otherwise, the
code needs to be changed to allow locking the runnable queue from within the
Swing thread.
Comment 1 Archie Cobbs 2007-04-26 12:16:17 UTC
Created attachment 20054 [details]
Patch to fix this bug

Perhaps it would be best to revert the patch applied for Bug #40681 and instead
solve that problem in another way that doesn't require locking the
RunnableQueue. The attached patch should do the trick.