Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8196100: javax/swing/text/JTextComponent/5074573/bug5074573.java fails
Reviewed-by: kizune
  • Loading branch information
mrserb committed Nov 26, 2020
1 parent a8e3eab commit 973255c469d794afe8ee74b24ddb5048bfcaadf7
@@ -464,6 +464,9 @@ protected void initializeDesktopProperties() {

@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
@@ -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.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,14 +88,14 @@
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;

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.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 OperationTimedOut() {
}
}

@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 IllegalThreadException() {
}

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 void realSync() throws OperationTimedOut, InfiniteLoop {
*
* @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 void realSync(final long timeout) throws OperationTimedOut, InfiniteLoop
// 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 void realSync(final long timeout) throws OperationTimedOut, InfiniteLoop
// 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 void realSync(final long timeout) throws OperationTimedOut, InfiniteLoop
* {@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 @@ private boolean isEQEmpty() {
* 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,32 +1585,32 @@ public void dispatch() {
// 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;
}
}

try {
Thread.sleep(MINIMAL_EDELAY);
Thread.sleep(MINIMAL_DELAY);
} catch (InterruptedException ie) {
throw new RuntimeException("Interrupted");
}
@@ -1579,7 +1619,7 @@ public void dispatch() {

// Lock to force write-cache flush for queueEmpty.
synchronized (waitLock) {
return !(queueEmpty && isEQEmpty() && queueWasEmpty);
return !(queueEmpty.get() && isEQEmpty() && queueWasEmpty);
}
}

@@ -2429,6 +2429,9 @@ public static long getEventNumber() {
*/
@Override
protected boolean syncNativeQueue(final long timeout) {
if (timeout <= 0) {
return false;
}
XBaseWindow win = XBaseWindow.getXAWTRootWindow();

if (oops_waiter == null) {
@@ -1234,7 +1234,7 @@ public void showOrHideTouchKeyboard(Component comp, AWTEvent e) {
///////////////////////////////////////////////////////////////////////////

@Override
public native boolean syncNativeQueue(final long timeout);
public native boolean syncNativeQueue(long timeout);

@Override
public boolean isDesktopSupported() {
@@ -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);
@@ -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
@@ -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");
}
}
}

0 comments on commit 973255c

Please sign in to comment.