8196100: javax/swing/text/JTextComponent/5074573/bug5074573.java fails

Reviewed-by: kizune
This commit is contained in:
Sergey Bylokhov 2020-11-26 08:43:29 +00:00
parent a8e3eabb6d
commit 973255c469
9 changed files with 222 additions and 50 deletions

View File

@ -464,6 +464,9 @@ public final class LWCToolkit extends LWToolkit {
@Override
protected boolean syncNativeQueue(long timeout) {
if (timeout <= 0) {
return false;
}
if (SunDragSourceContextPeer.isDragDropInProgress()
|| EventQueue.isDispatchThread()) {
// The java code started the DnD, but the native drag may still not

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2020, 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
@ -25,7 +25,40 @@
package sun.awt;
import java.awt.*;
import java.awt.AWTEvent;
import java.awt.AWTException;
import java.awt.Button;
import java.awt.Canvas;
import java.awt.Checkbox;
import java.awt.Choice;
import java.awt.Component;
import java.awt.Container;
import java.awt.DefaultKeyboardFocusManager;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FocusTraversalPolicy;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.KeyboardFocusManager;
import java.awt.Label;
import java.awt.MenuComponent;
import java.awt.Panel;
import java.awt.RenderingHints;
import java.awt.ScrollPane;
import java.awt.Scrollbar;
import java.awt.SystemTray;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.Window;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
@ -35,10 +68,10 @@ import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.awt.image.MultiResolutionImage;
import java.awt.image.Raster;
import java.awt.peer.FramePeer;
import java.awt.peer.KeyboardFocusManagerPeer;
import java.awt.peer.MouseInfoPeer;
import java.awt.peer.SystemTrayPeer;
import java.awt.peer.TrayIconPeer;
import java.io.File;
@ -55,6 +88,7 @@ import java.util.Map;
import java.util.Vector;
import java.util.WeakHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
@ -62,7 +96,6 @@ import sun.awt.im.InputContext;
import sun.awt.image.ByteArrayImageSource;
import sun.awt.image.FileImageSource;
import sun.awt.image.ImageRepresentation;
import java.awt.image.MultiResolutionImage;
import sun.awt.image.MultiResolutionToolkitImage;
import sun.awt.image.ToolkitImage;
import sun.awt.image.URLImageSource;
@ -72,7 +105,13 @@ import sun.security.action.GetBooleanAction;
import sun.security.action.GetPropertyAction;
import sun.util.logging.PlatformLogger;
import static java.awt.RenderingHints.*;
import static java.awt.RenderingHints.KEY_TEXT_ANTIALIASING;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_GASP;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON;
public abstract class SunToolkit extends Toolkit
implements ComponentFactory, InputMethodSupport, KeyboardFocusManagerPeerProvider {
@ -1377,10 +1416,6 @@ public abstract class SunToolkit extends Toolkit
}
}
@SuppressWarnings("serial")
public static class InfiniteLoop extends RuntimeException {
}
@SuppressWarnings("serial")
public static class IllegalThreadException extends RuntimeException {
public IllegalThreadException(String msg) {
@ -1391,14 +1426,14 @@ public abstract class SunToolkit extends Toolkit
}
public static final int DEFAULT_WAIT_TIME = 10000;
private static final int MAX_ITERS = 20;
private static final int MIN_ITERS = 0;
private static final int MINIMAL_EDELAY = 0;
private static final int MAX_ITERS = 100;
private static final int MIN_ITERS = 1;
private static final int MINIMAL_DELAY = 5;
/**
* Parameterless version of realsync which uses default timout (see DEFAUL_WAIT_TIME).
*/
public void realSync() throws OperationTimedOut, InfiniteLoop {
public void realSync() throws OperationTimedOut {
realSync(DEFAULT_WAIT_TIME);
}
@ -1447,13 +1482,21 @@ public abstract class SunToolkit extends Toolkit
*
* @param timeout the maximum time to wait in milliseconds, negative means "forever".
*/
public void realSync(final long timeout) throws OperationTimedOut, InfiniteLoop
{
public void realSync(final long timeout) throws OperationTimedOut {
if (EventQueue.isDispatchThread()) {
throw new IllegalThreadException("The SunToolkit.realSync() method cannot be used on the event dispatch thread (EDT).");
}
try {
// We should wait unconditionally for the first event on EDT
EventQueue.invokeAndWait(() -> {/*dummy implementation*/});
} catch (InterruptedException | InvocationTargetException ignored) {
}
int bigLoop = 0;
long end = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) + timeout;
do {
if (timeout(end) < 0) {
return;
}
// Let's do sync first
sync();
@ -1464,15 +1507,12 @@ public abstract class SunToolkit extends Toolkit
// to dispatch.
int iters = 0;
while (iters < MIN_ITERS) {
syncNativeQueue(timeout);
syncNativeQueue(timeout(end));
iters++;
}
while (syncNativeQueue(timeout) && iters < MAX_ITERS) {
while (syncNativeQueue(timeout(end)) && iters < MAX_ITERS) {
iters++;
}
if (iters >= MAX_ITERS) {
throw new InfiniteLoop();
}
// native requests were dispatched by X/Window Manager or Windows
// Moreover, we processed them all on Toolkit thread
@ -1483,21 +1523,23 @@ public abstract class SunToolkit extends Toolkit
// waitForIdle, we may end up with full EventQueue
iters = 0;
while (iters < MIN_ITERS) {
waitForIdle(timeout);
waitForIdle(timeout(end));
iters++;
}
while (waitForIdle(timeout) && iters < MAX_ITERS) {
while (waitForIdle(end) && iters < MAX_ITERS) {
iters++;
}
if (iters >= MAX_ITERS) {
throw new InfiniteLoop();
}
bigLoop++;
// Again, for Java events, it was simple to check for new Java
// events by checking event queue, but what if Java events
// resulted in native requests? Therefor, check native events again.
} while ((syncNativeQueue(timeout) || waitForIdle(timeout)) && bigLoop < MAX_ITERS);
} while ((syncNativeQueue(timeout(end)) || waitForIdle(end))
&& bigLoop < MAX_ITERS);
}
private long timeout(long end){
return end - TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
}
/**
@ -1508,10 +1550,8 @@ public abstract class SunToolkit extends Toolkit
* {@code true} if some events were processed,
* {@code false} otherwise.
*/
protected abstract boolean syncNativeQueue(final long timeout);
protected abstract boolean syncNativeQueue(long timeout);
private boolean eventDispatched;
private boolean queueEmpty;
private final Object waitLock = new Object();
private boolean isEQEmpty() {
@ -1527,13 +1567,13 @@ public abstract class SunToolkit extends Toolkit
* necessary, {@code false} otherwise.
*/
@SuppressWarnings("serial")
protected final boolean waitForIdle(final long timeout) {
private final boolean waitForIdle(final long end) {
flushPendingEvents();
final boolean queueWasEmpty;
final AtomicBoolean queueEmpty = new AtomicBoolean();
final AtomicBoolean eventDispatched = new AtomicBoolean();
synchronized (waitLock) {
queueWasEmpty = isEQEmpty();
queueEmpty = false;
eventDispatched = false;
postEvent(AppContext.getAppContext(),
new PeerEvent(getSystemEventQueueImpl(), null, PeerEvent.LOW_PRIORITY_EVENT) {
@Override
@ -1545,24 +1585,24 @@ public abstract class SunToolkit extends Toolkit
// flush Java events again.
int iters = 0;
while (iters < MIN_ITERS) {
syncNativeQueue(timeout);
syncNativeQueue(timeout(end));
iters++;
}
while (syncNativeQueue(timeout) && iters < MAX_ITERS) {
while (syncNativeQueue(timeout(end)) && iters < MAX_ITERS) {
iters++;
}
flushPendingEvents();
synchronized(waitLock) {
queueEmpty = isEQEmpty();
eventDispatched = true;
queueEmpty.set(isEQEmpty());
eventDispatched.set(true);
waitLock.notifyAll();
}
}
});
try {
while (!eventDispatched) {
waitLock.wait();
while (!eventDispatched.get() && timeout(end) > 0) {
waitLock.wait(timeout(end));
}
} catch (InterruptedException ie) {
return false;
@ -1570,7 +1610,7 @@ public abstract class SunToolkit extends Toolkit
}
try {
Thread.sleep(MINIMAL_EDELAY);
Thread.sleep(MINIMAL_DELAY);
} catch (InterruptedException ie) {
throw new RuntimeException("Interrupted");
}
@ -1579,7 +1619,7 @@ public abstract class SunToolkit extends Toolkit
// Lock to force write-cache flush for queueEmpty.
synchronized (waitLock) {
return !(queueEmpty && isEQEmpty() && queueWasEmpty);
return !(queueEmpty.get() && isEQEmpty() && queueWasEmpty);
}
}

View File

@ -2429,6 +2429,9 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
*/
@Override
protected boolean syncNativeQueue(final long timeout) {
if (timeout <= 0) {
return false;
}
XBaseWindow win = XBaseWindow.getXAWTRootWindow();
if (oops_waiter == null) {

View File

@ -1234,7 +1234,7 @@ public final class WToolkit extends SunToolkit implements Runnable {
///////////////////////////////////////////////////////////////////////////
@Override
public native boolean syncNativeQueue(final long timeout);
public native boolean syncNativeQueue(long timeout);
@Override
public boolean isDesktopSupported() {

View File

@ -3004,6 +3004,9 @@ Java_sun_awt_windows_WToolkit_hideTouchKeyboard(JNIEnv *env, jobject self)
JNIEXPORT jboolean JNICALL
Java_sun_awt_windows_WToolkit_syncNativeQueue(JNIEnv *env, jobject self, jlong timeout)
{
if (timeout <= 0) {
return JNI_FALSE;
}
AwtToolkit & tk = AwtToolkit::GetInstance();
DWORD eventNumber = tk.eventNumber;
tk.PostMessage(WM_SYNC_WAIT, 0, 0);

View File

@ -758,7 +758,6 @@ javax/swing/SwingUtilities/TestBadBreak/TestBadBreak.java 8160720 generic-all
javax/swing/plaf/basic/Test6984643.java 8198340 windows-all
javax/swing/text/DefaultCaret/HidingSelection/HidingSelectionTest.java 8194048 windows-all
javax/swing/text/DefaultCaret/HidingSelection/MultiSelectionTest.java 8213562 linux-all
javax/swing/text/JTextComponent/5074573/bug5074573.java 8196100 windows-all
javax/swing/JFileChooser/6798062/bug6798062.java 8146446 windows-all
javax/swing/JComboBox/8182031/ComboPopupTest.java 8196465 linux-all,macosx-all
javax/swing/JFileChooser/6738668/bug6738668.java 8194946 generic-all

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2020, 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.
*/
import java.awt.EventQueue;
import java.awt.Robot;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @test
* @key headful
* @bug 8196100
* @summary Checks that current event is flushed by the Robot.waitForIdle()
*/
public final class FlushCurrentEvent {
public static void main(String[] args) throws Exception {
Robot robot = new Robot();
AtomicBoolean done = new AtomicBoolean();
EventQueue.invokeLater(() -> {
robot.delay(15000);
done.set(true);
});
robot.waitForIdle();
if (!done.get()) {
throw new RuntimeException("Current event was not flushed");
}
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2020, 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.
*/
import java.awt.Frame;
import java.awt.Robot;
import java.util.concurrent.TimeUnit;
/**
* @test
* @key headful
* @bug 8196100
* @summary Checks that Robot.waitForIdle() works if EDT is overloaded
*/
public final class InfiniteLoopException {
public static void main(String[] args) throws Exception {
Frame frame = new Frame();
try {
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
test(frame);
} finally {
frame.dispose();
}
}
private static void test(Frame frame) throws Exception {
Runnable repaint = () -> {
while (frame.isDisplayable()) {
frame.repaint();
}
};
new Thread(repaint).start();
new Thread(repaint).start();
new Thread(repaint).start();
Robot robot = new Robot();
long start = System.nanoTime();
robot.waitForIdle();
long time = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start);
if (time > 20) {
throw new RuntimeException("Too slow:" + time);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2020, 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
@ -24,18 +24,27 @@
/*
* @test
* @key headful
* @bug 5074573
* @bug 5074573 8196100
* @summary tests delte-next-word and delete-prev-word actions for all text compnents and all look&feels
* @author Igor Kushnirskiy
* @run main bug5074573
*/
import java.util.*;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.event.KeyEvent;
import java.util.Arrays;
import java.util.List;
import javax.swing.JEditorPane;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPasswordField;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.text.Caret;
import javax.swing.text.JTextComponent;
public class bug5074573 {
@ -148,6 +157,7 @@ public class bug5074573 {
textComponent.setText(testString);
frame.add(textComponent);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
textComponent.requestFocus();
Caret caret = textComponent.getCaret();