The dead-lock happens when accessing SynchronizedViewerState.sourceOrder() method from a synchronized block in MultiResolutionRenderer. At the same time, SynchronizedViewerState.setViewerTransform() tries to MultiResolutionRenderer.requestRepaint (which is synchronized) form a synchronized block.
It is surprising that this has not blown up somewhere else yet, because there are other uses of SynchronizedViewerState methods in synchronized blocks of MultiResolutionRenderer.
Found one Java-level deadlock:
=============================
"PainterThread":
waiting to lock monitor 0x00007fa1f27e71e8 (object 0x00000006c15bc660, a bdv.viewer.SynchronizedViewerState),
which is held by "AWT-EventQueue-0"
"AWT-EventQueue-0":
waiting to lock monitor 0x00007fa1f15ae0e8 (object 0x00000006c2049fa8, a bdv.viewer.render.MultiResolutionRenderer),
which is held by "PainterThread"
Java stack information for the threads listed above:
===================================================
"PainterThread":
at bdv.viewer.SynchronizedViewerState.sourceOrder(SynchronizedViewerState.java:589)
- waiting to lock <0x00000006c15bc660> (a bdv.viewer.SynchronizedViewerState)
at org.embl.mobie.viewer.bdv.render.AccumulateAlphaBlendingProjectorARGB.getOrder(AccumulateAlphaBlendingProjectorARGB.java:80)
- locked <0x00000006c1f0de90> (a java.lang.Class for org.embl.mobie.viewer.bdv.render.AccumulateAlphaBlendingProjectorARGB)
at org.embl.mobie.viewer.bdv.render.AccumulateAlphaBlendingProjectorARGB.<init>(AccumulateAlphaBlendingProjectorARGB.java:71)
at org.embl.mobie.viewer.bdv.render.AccumulateAlphaBlendingProjectorARGBFactory.createProjector(AccumulateAlphaBlendingProjectorARGBFactory.java:55)
at bdv.viewer.render.ProjectorFactory.createProjector(ProjectorFactory.java:191)
at bdv.viewer.render.MultiResolutionRenderer.createProjector(MultiResolutionRenderer.java:668)
at bdv.viewer.render.MultiResolutionRenderer.paintFullFrame(MultiResolutionRenderer.java:478)
- locked <0x00000006c2049fa8> (a bdv.viewer.render.MultiResolutionRenderer)
at bdv.viewer.render.MultiResolutionRenderer.paint(MultiResolutionRenderer.java:452)
at bdv.viewer.ViewerPanel.paint(ViewerPanel.java:464)
at bdv.viewer.render.PainterThread.run(PainterThread.java:82)
"AWT-EventQueue-0":
at bdv.viewer.render.MultiResolutionRenderer.requestRepaint(MultiResolutionRenderer.java:339)
- waiting to lock <0x00000006c2049fa8> (a bdv.viewer.render.MultiResolutionRenderer)
at bdv.viewer.ViewerPanel.requestRepaint(ViewerPanel.java:488)
at bdv.viewer.ViewerPanel.viewerStateChanged(ViewerPanel.java:622)
at bdv.viewer.BasicViewerState.lambda$notifyListeners$3(BasicViewerState.java:1650)
at bdv.viewer.BasicViewerState$$Lambda$267/1019831085.accept(Unknown Source)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at bdv.viewer.BasicViewerState.notifyListeners(BasicViewerState.java:1650)
at bdv.viewer.BasicViewerState.setViewerTransform(BasicViewerState.java:353)
at bdv.viewer.SynchronizedViewerState.setViewerTransform(SynchronizedViewerState.java:170)
@tischi reported a dead-lock issue on gitter.
The dead-lock happens when accessing
SynchronizedViewerState.sourceOrder()
method from asynchronized
block inMultiResolutionRenderer
. At the same time,SynchronizedViewerState.setViewerTransform()
tries toMultiResolutionRenderer.requestRepaint
(which issynchronized
) form asynchronized
block.It is surprising that this has not blown up somewhere else yet, because there are other uses of
SynchronizedViewerState
methods insynchronized
blocks ofMultiResolutionRenderer
.