JBR-6117 Wayland: JVM shutdown hang

(cherry picked from commit 20b2eeb0cc)
This commit is contained in:
Maxim Kartashev
2023-09-27 12:56:43 +04:00
committed by jbrbot
parent da6cefe3b6
commit 5df452f632
4 changed files with 151 additions and 0 deletions

View File

@@ -653,6 +653,12 @@ public class WLComponentPeer implements ComponentPeer {
@Override
public void dispose() {
SurfaceData oldData = surfaceData;
surfaceData = null;
if (oldData != null) {
oldData.invalidate();
}
WLToolkit.targetDisposedPeer(target, this);
performLocked(() -> {
assert(!isVisible());
nativeDisposeFrame(nativePtr);

View File

@@ -28,6 +28,7 @@ package sun.awt.wl;
import jdk.internal.misc.InnocuousThread;
import sun.awt.AWTAccessor;
import sun.awt.AWTAutoShutdown;
import sun.awt.AppContext;
import sun.awt.LightweightFrame;
import sun.awt.PeerEvent;
@@ -204,12 +205,14 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
@Override
public void run() {
while(true) {
AWTAutoShutdown.notifyToolkitThreadFree(); // will now wait for events
int result = readEvents();
if (result == READ_RESULT_ERROR) {
log.severe("Wayland protocol I/O error");
// TODO: display disconnect handling here?
break;
} else if (result == READ_RESULT_FINISHED_WITH_EVENTS) {
AWTAutoShutdown.notifyToolkitThreadBusy(); // busy processing events
SunToolkit.postEvent(AppContext.getAppContext(), new PeerEvent(this, () -> {
WLToolkit.awtLock();
try {

View File

@@ -805,6 +805,7 @@ jdk_since_checks = \
# Wayland tests to be executed with -Dawt.toolkit.name=WLToolkit
jdk_awt_wayland = \
:jdk_awt \
jb/java/awt/wayland \
-com/apple/eawt \
-com/apple/laf \
-sun/awt \

View File

@@ -0,0 +1,141 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, JetBrains s.r.o.. 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.
*/
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.concurrent.CountDownLatch;
/*
* @test
* @summary Verifies that the program finishes after disposing of JFrame
* @run main WLShutdownTest
*/
public class WLShutdownTest {
private static JFrame frame = null;
public static void main(String[] args) throws Exception {
final CountDownLatch latchShownFrame = new CountDownLatch(1);
final CountDownLatch latchClosedFrame = new CountDownLatch(1);
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
frame = new JFrame("TEST");
frame.addComponentListener(new ComponentAdapter() {
@Override
public void componentShown(ComponentEvent e) {
latchShownFrame.countDown();
}
});
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
latchClosedFrame.countDown();
}
});
JPanel panel = new JPanel() {
int n = 0;
@Override
protected void paintComponent(Graphics g) {
System.out.print("P");
g.setColor((n++ % 2 == 0) ? Color.RED : Color.BLUE);
g.fillRect(0, 0, getWidth(), getHeight());
System.out.print("Q");
}
};
panel.setPreferredSize(new Dimension(800, 800));
panel.setBackground(Color.BLACK);
frame.add(panel);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
System.out.print(">>");
}
});
// Wait frame to be shown:
latchShownFrame.await();
System.out.print(":>>");
final long startTime = System.currentTimeMillis();
final long endTime = startTime + 3000;
// Start 1st measurement:
repaint();
for (; ; ) {
System.out.print(".");
repaint();
if (System.currentTimeMillis() >= endTime) {
break;
}
sleep();
} // end measurements
SwingUtilities.invokeAndWait(() -> {
frame.setVisible(false);
frame.dispose();
});
latchClosedFrame.await();
System.out.print("<<\n");
frame = null; // free static ref: gc
System.out.println("Waiting AWT to shutdown JVM soon ...");
}
static void repaint() throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
frame.repaint();
}
});
}
static void sleep() {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
ie.printStackTrace(System.err);
}
}
}