From c8358923f7ce7e8ab9dfb5f05cd26f60a5523150 Mon Sep 17 00:00:00 2001 From: Alexander Zvegintsev <azvegint@openjdk.org> Date: Mon, 22 Jun 2015 15:43:40 +0300 Subject: [PATCH] 8129116: Deadlock with multimonitor fullscreen windows Reviewed-by: alexsch, serb --- .../unix/classes/sun/awt/X11/XWindowPeer.java | 45 +++++++------ .../MultimonDeadlockTest.java | 66 +++++++++++++++++++ 2 files changed, 91 insertions(+), 20 deletions(-) create mode 100644 jdk/test/java/awt/FullScreen/MultimonFullscreenTest/MultimonDeadlockTest.java diff --git a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java index 585185308df..4a948698705 100644 --- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java @@ -682,28 +682,33 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, GraphicsConfiguration newGC = null; Rectangle screenBounds; - for (int i = 0; i < gds.length; i++) { - screenBounds = gds[i].getDefaultConfiguration().getBounds(); - if (newBounds.intersects(screenBounds)) { - horizAmt = Math.min(newBounds.x + newBounds.width, - screenBounds.x + screenBounds.width) - - Math.max(newBounds.x, screenBounds.x); - vertAmt = Math.min(newBounds.y + newBounds.height, - screenBounds.y + screenBounds.height)- - Math.max(newBounds.y, screenBounds.y); - intAmt = horizAmt * vertAmt; - if (intAmt == area) { - // Completely on this screen - done! - newScreenNum = i; - newGC = gds[i].getDefaultConfiguration(); - break; - } - if (intAmt > largestAmt) { - largestAmt = intAmt; - newScreenNum = i; - newGC = gds[i].getDefaultConfiguration(); + XToolkit.awtUnlock(); + try { + for (int i = 0; i < gds.length; i++) { + screenBounds = gds[i].getDefaultConfiguration().getBounds(); + if (newBounds.intersects(screenBounds)) { + horizAmt = Math.min(newBounds.x + newBounds.width, + screenBounds.x + screenBounds.width) - + Math.max(newBounds.x, screenBounds.x); + vertAmt = Math.min(newBounds.y + newBounds.height, + screenBounds.y + screenBounds.height)- + Math.max(newBounds.y, screenBounds.y); + intAmt = horizAmt * vertAmt; + if (intAmt == area) { + // Completely on this screen - done! + newScreenNum = i; + newGC = gds[i].getDefaultConfiguration(); + break; + } + if (intAmt > largestAmt) { + largestAmt = intAmt; + newScreenNum = i; + newGC = gds[i].getDefaultConfiguration(); + } } } + } finally { + XToolkit.awtLock(); } if (newScreenNum != curScreenNum) { if (log.isLoggable(PlatformLogger.Level.FINEST)) { diff --git a/jdk/test/java/awt/FullScreen/MultimonFullscreenTest/MultimonDeadlockTest.java b/jdk/test/java/awt/FullScreen/MultimonFullscreenTest/MultimonDeadlockTest.java new file mode 100644 index 00000000000..c457245c3f1 --- /dev/null +++ b/jdk/test/java/awt/FullScreen/MultimonFullscreenTest/MultimonDeadlockTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 8129116 + @summary Deadlock with multimonitor fullscreen windows. + @run main/timeout=20 MultimonDeadlockTest + */ +import java.awt.*; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.lang.reflect.InvocationTargetException; + +public class MultimonDeadlockTest { + + public static void main(String argv[]) { + final GraphicsDevice[] devices = GraphicsEnvironment + .getLocalGraphicsEnvironment() + .getScreenDevices(); + if (devices.length < 2) { + System.out.println("It's a multiscreen test... skipping!"); + return; + } + + Frame frames[] = new Frame[devices.length]; + try { + EventQueue.invokeAndWait(() -> { + for (int i = 0; i < devices.length; i++) { + frames[i] = new Frame(); + frames[i].setSize(100, 100); + frames[i].setBackground(Color.BLUE); + devices[i].setFullScreenWindow(frames[i]); + } + }); + Thread.sleep(5000); + } catch (InterruptedException | InvocationTargetException ex) { + } finally { + for (int i = 0; i < devices.length; i++) { + devices[i].setFullScreenWindow(null); + frames[i].dispose(); + } + } + + } +}