JDK-8078606 : Deadlock in awt clipboard
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 8,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • CPU: generic
  • Submitted: 2015-04-24
  • Updated: 2015-09-29
  • Resolved: 2015-06-04
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 8 JDK 9
8u60Fixed 9 b70Fixed
Description
Our automated tests encountered this. Although it will be difficult to
reproduce, it looks like a simple deadlock between a monitor lock and a
ReentrantLock in the AWT clipboard support.

Deadlock detected:
==================
"System clipboard synchronizer":
  waiting to lock sun.awt.X11.XClipboard@59383e0f
  which is held by "AWT-EventQueue-0"
"AWT-EventQueue-0":
  waiting to lock
java.util.concurrent.locks.ReentrantLock$NonfairSync@2943444d
  which is held by "AWT-XAWT"
"AWT-XAWT":
  waiting to lock java.lang.Object@7ac3597e
  which is held by "AWT-EventQueue-0" 

Stacks for threads in question:

"AWT-EventQueue-0" Id=15 WAITING on
java.util.concurrent.locks.ReentrantLock$NonfairSync@2943444d owned by
"AWT-XAWT" Id=12
at sun.misc.Unsafe.park(Native Method)
-  waiting on java.util.concurrent.locks.ReentrantLock$NonfairSync@2943444d
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
at sun.awt.SunToolkit.awtLock(SunToolkit.java:253)
at sun.awt.X11.XRootWindow.getInstance(XRootWindow.java:36)
at sun.awt.X11.XBaseWindow.getXAWTRootWindow(XBaseWindow.java:412)
at sun.awt.X11.XClipboard.registerClipboardViewerChecked(XClipboard.java:166)
-  locked java.lang.Object@7ac3597e
at sun.awt.datatransfer.SunClipboard.addFlavorListener(SunClipboard.java:377)
-  locked sun.awt.X11.XClipboard@59383e0f
...

"AWT-XAWT" Id=12 BLOCKED on java.lang.Object@7ac3597e owned by
"AWT-EventQueue-0" Id=15
at sun.awt.X11.XClipboard$CheckChangeTimerTask.run(XClipboard.java:180)
-  blocked on java.lang.Object@7ac3597e
at sun.awt.X11.XToolkit.callTimeoutTasks(XToolkit.java:1922)
at sun.awt.X11.XToolkit.run(XToolkit.java:558)
at sun.awt.X11.XToolkit.run(XToolkit.java:523)
at java.lang.Thread.run(Thread.java:745)
Number of locked synchronizers = 1
- java.util.concurrent.locks.ReentrantLock$NonfairSync@2943444d 
Comments
Webrev: http://cr.openjdk.java.net/~anashaty/8078606/webrev.00/
08-05-2015

1. XClipboard.registerClipboardViewerChecked acquires XCliboard lock first, then acquires AWTLock (within the XWindow.getXAWTRootWindow() call). It makes sense to acquire AWTLock prior to acquiring XClipboard lock. 2. The XRootWindow singleton is better to acquire the AWTLock only upon initialization. This will still leave a chance for deadlock on initialization, however will reduce the deadlock possibility on subsequent calls
08-05-2015

Reproduced with jdk8 with inserting a couple of sleep() into XClipboard.
08-05-2015