I got the current CVS HEAD TM4Nav to deadlock by simply loading an XTM file. (My machine is running in SMP mode.)
This is what Ctrl-'\' returns:
"Thread-5":
waiting to lock monitor 0x08106dac (object 0x52d208a8, a java.awt.Component$AWTTreeLock),
which is held by "AWT-EventQueue-0"
"AWT-EventQueue-0":
waiting to lock monitor 0x08106eec (object 0x531fa3f0, a com.touchgraph.graphlayout.TGPanel),
which is held by "Thread-5"
"Thread-5":
at java.awt.Component.reshape(Component.java:1858)
- waiting to lock <0x52d208a8> (a java.awt.Component$AWTTreeLock)
at javax.swing.JComponent.reshape(JComponent.java:3940)
at java.awt.Component.setBounds(Component.java:1847)
at javax.swing.plaf.basic.BasicScrollBarUI.layoutHScrollbar(BasicScrollBarUI.java:732)
at javax.swing.plaf.basic.BasicScrollBarUI.layoutContainer(BasicScrollBarUI.java:775)
at javax.swing.plaf.basic.BasicScrollBarUI$ModelListener.stateChanged(BasicScrollBarUI.java:935)
at javax.swing.DefaultBoundedRangeModel.fireStateChanged(DefaultBoundedRangeModel.java:348)
at javax.swing.DefaultBoundedRangeModel.setRangeProperties(DefaultBoundedRangeModel.java:285)
at javax.swing.DefaultBoundedRangeModel.setValue(DefaultBoundedRangeModel.java:151)
at javax.swing.JScrollBar.setValue(JScrollBar.java:441)
at com.touchgraph.graphlayout.interaction.HVScroll$DScrollbar.setIValue(HVScroll.java:189)
at com.touchgraph.graphlayout.interaction.HVScroll$DScrollbar.setDValue(HVScroll.java:192)
at com.touchgraph.graphlayout.interaction.HVScroll.graphMoved(HVScroll.java:161)
at com.touchgraph.graphlayout.TGPanel.fireMovedEvent(TGPanel.java:407)
at com.touchgraph.graphlayout.TGPanel.repaintAfterMove(TGPanel.java:755)
- locked <0x531fa3f0> (a com.touchgraph.graphlayout.TGPanel)
at com.touchgraph.graphlayout.TGLayout.relax(TGLayout.java:321)
- locked <0x52e6f1f0> (a com.touchgraph.graphlayout.TGLayout)
at com.touchgraph.graphlayout.TGLayout.run(TGLayout.java:336)
at java.lang.Thread.run(Thread.java:595)
"AWT-EventQueue-0":
at com.touchgraph.graphlayout.TGPanel.paint(TGPanel.java:793)
- waiting to lock <0x531fa3f0> (a com.touchgraph.graphlayout.TGPanel)
at javax.swing.JComponent.paintChildren(JComponent.java:842)
- locked <0x52d208a8> (a java.awt.Component$AWTTreeLock)
at javax.swing.JComponent.paint(JComponent.java:1014)
at javax.swing.JComponent.paintChildren(JComponent.java:842)
- locked <0x52d208a8> (a java.awt.Component$AWTTreeLock)
at javax.swing.JComponent.paint(JComponent.java:1014)
at javax.swing.JComponent.paintChildren(JComponent.java:842)
- locked <0x52d208a8> (a java.awt.Component$AWTTreeLock)
at javax.swing.JSplitPane.paintChildren(JSplitPane.java:1021)
at javax.swing.JComponent.paint(JComponent.java:1014)
at javax.swing.JComponent.paintWithOffscreenBuffer(JComponent.java:4963)
at javax.swing.JComponent.paintDoubleBuffered(JComponent.java:4916)
at javax.swing.JComponent._paintImmediately(JComponent.java:4859)
at javax.swing.JComponent.paintImmediately(JComponent.java:4666)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:451)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:114)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
Found 1 deadlock.
It seems that TGLayout
(1) either runs separately of the event dispatch thread while it should not
(2) or effectively calls Swing methods while it should not (because calling Swing methods is only safe within the event dispatch thread).