JDK-6786210 : Deadlock occurs when handling mouseLeave on XToolkit
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6u10,6u12
  • Priority: P1
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,linux
  • CPU: generic,x86
  • Submitted: 2008-12-17
  • Updated: 2011-01-19
  • Resolved: 2009-01-14
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6u12 b04Fixed
Related Reports
Duplicate :  
Duplicate :  
Description
The problem is reported here: http://forums.java.net/jive/thread.jspa?messageID=322051

The stack trace of the deadlock:

Name: AWT-XAWT
State: BLOCKED on sun.awt.X11.XDialogPeer@25ec1ff7 owned by: AWT-EventQueue-1
Total blocked: 29 Total waited: 1,837

Stack trace: 
sun.awt.X11.XWindow.setMouseAbove(XWindow.java:789)
sun.awt.X11.XWindowPeer.setMouseAbove(XWindowPeer.java:1012)
sun.awt.X11.XWindow.leaveNotify(XWindow.java:799)
sun.awt.X11.XWindow.handleXCrossingEvent(XWindow.java:812)
sun.awt.X11.XWindowPeer.handleXCrossingEvent(XWindowPeer.java:1765)
sun.awt.X11.XBaseWindow.dispatchEvent(XBaseWindow.java:1119)
sun.awt.X11.XBaseWindow.dispatchToWindow(XBaseWindow.java:1079)
sun.awt.X11.XToolkit.dispatchEvent(XToolkit.java:475)
sun.awt.X11.XToolkit.run(XToolkit.java:588)
sun.awt.X11.XToolkit.run(XToolkit.java:523)
java.lang.Thread.run(Thread.java:619)

Name: AWT-EventQueue-1
State: WAITING on java.util.concurrent.locks.ReentrantLock$NonfairSync@48f2d715 owned by: AWT-XAWT
Total blocked: 18,133 Total waited: 19,299

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:747)
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:778)
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1114)
java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:186)
java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
sun.awt.SunToolkit.awtLock(SunToolkit.java:241)
sun.awt.X11.XDropTargetRegistry.unregisterDropSite(XDropTargetRegistry.java:569)
sun.awt.X11.XWindowPeer.removeDropTarget(XWindowPeer.java:1634)
- locked sun.awt.X11.XDialogPeer@25ec1ff7
sun.awt.X11.XComponentPeer.removeDropTarget(XComponentPeer.java:1511)
java.awt.dnd.DropTarget.removeNotify(DropTarget.java:517)
java.awt.Component.removeNotify(Component.java:6721)
- locked java.awt.Component$AWTTreeLock@69d8ad6a
java.awt.Container.removeNotify(Container.java:2611)
- locked java.awt.Component$AWTTreeLock@69d8ad6a
javax.swing.JComponent.removeNotify(JComponent.java:4699)
org.openide.explorer.view.ListView$NbList.removeNotify(ListView.java:834)
java.awt.Container.removeNotify(Container.java:2604)
- locked java.awt.Component$AWTTreeLock@69d8ad6a
javax.swing.JComponent.removeNotify(JComponent.java:4699)
java.awt.Container.removeNotify(Container.java:2604)
- locked java.awt.Component$AWTTreeLock@69d8ad6a
javax.swing.JComponent.removeNotify(JComponent.java:4699)
org.openide.explorer.view.ListView.removeNotify(ListView.java:607)
java.awt.Container.removeNotify(Container.java:2604)
- locked java.awt.Component$AWTTreeLock@69d8ad6a
javax.swing.JComponent.removeNotify(JComponent.java:4699)
java.awt.Container.removeNotify(Container.java:2604)
- locked java.awt.Component$AWTTreeLock@69d8ad6a
javax.swing.JComponent.removeNotify(JComponent.java:4699)
java.awt.Container.removeNotify(Container.java:2604)
- locked java.awt.Component$AWTTreeLock@69d8ad6a
javax.swing.JComponent.removeNotify(JComponent.java:4699)
java.awt.Container.removeNotify(Container.java:2604)
- locked java.awt.Component$AWTTreeLock@69d8ad6a
javax.swing.JComponent.removeNotify(JComponent.java:4699)
java.awt.Container.removeNotify(Container.java:2604)
- locked java.awt.Component$AWTTreeLock@69d8ad6a
javax.swing.JComponent.removeNotify(JComponent.java:4699)
java.awt.Container.removeNotify(Container.java:2604)
- locked java.awt.Component$AWTTreeLock@69d8ad6a
javax.swing.JComponent.removeNotify(JComponent.java:4699)
java.awt.Container.removeNotify(Container.java:2604)
- locked java.awt.Component$AWTTreeLock@69d8ad6a
javax.swing.JComponent.removeNotify(JComponent.java:4699)
java.awt.Container.removeNotify(Container.java:2604)
- locked java.awt.Component$AWTTreeLock@69d8ad6a
javax.swing.JComponent.removeNotify(JComponent.java:4699)
java.awt.Container.removeNotify(Container.java:2604)
- locked java.awt.Component$AWTTreeLock@69d8ad6a
javax.swing.JComponent.removeNotify(JComponent.java:4699)
javax.swing.JRootPane.removeNotify(JRootPane.java:750)
java.awt.Container.removeNotify(Container.java:2604)
- locked java.awt.Component$AWTTreeLock@69d8ad6a
java.awt.Window.removeNotify(Window.java:685)
- locked java.awt.Component$AWTTreeLock@69d8ad6a
org.netbeans.core.windows.services.NbPresenter.removeNotify(NbPresenter.java:349)
java.awt.Window$1DisposeAction.run(Window.java:1013)
java.awt.Window.doDispose(Window.java:1025)
java.awt.Dialog.doDispose(Dialog.java:1248)
java.awt.Window.dispose(Window.java:972)
org.openide.explorer.propertysheet.PropertyDialogManager.actionPerformed(PropertyDialogManager.java:543)
org.netbeans.core.windows.services.NbPresenter$ButtonListener.actionPerformed(NbPresenter.java:1137)
javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
java.awt.Component.processMouseEvent(Component.java:6213)
javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
java.awt.Component.processEvent(Component.java:5978)
java.awt.Container.processEvent(Container.java:2036)
java.awt.Component.dispatchEventImpl(Component.java:4580)
java.awt.Container.dispatchEventImpl(Container.java:2094)
java.awt.Component.dispatchEvent(Component.java:4410)
java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4551)
java.awt.LightweightDispatcher.processMouseEvent(Container.java:4215)
java.awt.LightweightDispatcher.dispatchEvent(Container.java:4145)
java.awt.Container.dispatchEventImpl(Container.java:2080)
java.awt.Window.dispatchEventImpl(Window.java:2475)
java.awt.Component.dispatchEvent(Component.java:4410)
java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:104)
java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:178)
java.awt.Dialog$1.run(Dialog.java:1051)
java.awt.Dialog$3.run(Dialog.java:1103)
java.security.AccessController.doPrivileged(Native Method)
java.awt.Dialog.show(Dialog.java:1101)
org.netbeans.core.windows.services.NbPresenter.superShow(NbPresenter.java:867)
org.netbeans.core.windows.services.NbPresenter.doShow(NbPresenter.java:901)
org.netbeans.core.windows.services.NbPresenter.run(NbPresenter.java:889)
org.netbeans.core.windows.services.NbPresenter.run(NbPresenter.java:109)
org.openide.util.Mutex.doEventAccess(Mutex.java:1355)
org.openide.util.Mutex.readAccess(Mutex.java:268)
org.netbeans.core.windows.services.NbPresenter.show(NbPresenter.java:874)
java.awt.Component.show(Component.java:1513)
java.awt.Component.setVisible(Component.java:1465)
java.awt.Window.setVisible(Window.java:841)
java.awt.Dialog.setVisible(Dialog.java:991)
org.openide.explorer.propertysheet.CustomEditorAction.actionPerformed(CustomEditorAction.java:318)
org.openide.explorer.propertysheet.SheetTable.processMouseEvent(SheetTable.java:710)
java.awt.Component.processEvent(Component.java:5978)
java.awt.Container.processEvent(Container.java:2036)
java.awt.Component.dispatchEventImpl(Component.java:4580)
java.awt.Container.dispatchEventImpl(Container.java:2094)
java.awt.Component.dispatchEvent(Component.java:4410)
java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4551)
java.awt.LightweightDispatcher.processMouseEvent(Container.java:4212)
java.awt.LightweightDispatcher.dispatchEvent(Container.java:4145)
java.awt.Container.dispatchEventImpl(Container.java:2080)
java.awt.Window.dispatchEventImpl(Window.java:2475)
java.awt.Component.dispatchEvent(Component.java:4410)
java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:104)
java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Comments
SUGGESTED FIX --- old/src/solaris/classes/sun/awt/X11/XWindow.java 2008-12-22 17:20:38.000000000 +0300 +++ new/src/solaris/classes/sun/awt/X11/XWindow.java 2008-12-22 17:20:38.000000000 +0300 @@ -786,11 +786,19 @@ native boolean haveCurrentX11InputMethodInstance(); private boolean mouseAboveMe; - public synchronized boolean isMouseAbove() { - return mouseAboveMe; + + // We consider peers non-serializable, hence the use of 'final'. + private final Object peerLock = new Object(); + + public boolean isMouseAbove() { + synchronized (peerLock) { + return mouseAboveMe; + } } - protected synchronized void setMouseAbove(boolean above) { - mouseAboveMe = above; + protected void setMouseAbove(boolean above) { + synchronized (peerLock) { + mouseAboveMe = above; + } } protected void enterNotify(long window) {
22-12-2008

EVALUATION This is a regression of 6730439 which introduced the method XWindow.setMouseAbove(). This method uses 'this' synchronization on the window peer object to synchronize access to the private boolean data field. However this is a bad practice since many other methods use 'this' synchronization in different cases. It may cause deadlocks under some circumstances, one of them is reported as this bug. The methods (as well as the method isMouseAbove()) must be changed to use some private object for synchronization purposes.
17-12-2008