aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tarasov <anton.tarasov@jetbrains.com>2022-04-11 21:18:32 +0300
committerAnton Tarasov <anton.tarasov@jetbrains.com>2022-04-12 15:50:50 +0300
commit7efb0075bc846235a03c040b70c9abb522fb08e0 (patch)
tree2bc6fb93c94f9a6e2951d4ad0cf2b575c4ba5c84
parent413ff95d63afb99bb09ec2b901f0ed2c877e591b (diff)
downloadJetBrainsRuntime-jb17-b390.tar.gz
JBR-4362 [mac] system menu opens with duplicated itemsjb17-b390
(cherry picked from commit e32defe49d3aed2ab438ce8d14a387b9679fae43)
-rw-r--r--src/java.desktop/share/classes/sun/awt/AWTThreading.java11
-rw-r--r--test/jdk/jb/java/awt/Toolkit/AWTThreadingTest.java60
-rw-r--r--test/jdk/jb/java/awt/Toolkit/LWCToolkitInvokeAndWaitTest.java6
-rw-r--r--test/jdk/jb/java/awt/Toolkit/helper/ToolkitTestHelper.java11
-rw-r--r--test/jdk/jbA11yProblemList.txt5
5 files changed, 84 insertions, 9 deletions
diff --git a/src/java.desktop/share/classes/sun/awt/AWTThreading.java b/src/java.desktop/share/classes/sun/awt/AWTThreading.java
index b19eaecbec9..cf7e8988d46 100644
--- a/src/java.desktop/share/classes/sun/awt/AWTThreading.java
+++ b/src/java.desktop/share/classes/sun/awt/AWTThreading.java
@@ -306,19 +306,24 @@ public class AWTThreading {
@Override
public void dispatch() {
- completeIfNotYet(super::dispatch);
- futureResult.complete(null);
+ // Should not complete if competion has already started.
+ if (completeIfNotYet(super::dispatch)) {
+ futureResult.complete(null);
+ }
}
public void dispose(String reason) {
completeIfNotYet(() -> AWTAccessor.getInvocationEventAccessor().dispose(this));
+ // Should complete exceptionally regardless of whether completetion has alredy started or hasn't.
futureResult.completeExceptionally(new Throwable(reason));
}
- private void completeIfNotYet(Runnable competeRunnable) {
+ private boolean completeIfNotYet(Runnable competeRunnable) {
if (!isCompletionStarted.getAndSet(true)) {
competeRunnable.run();
+ return true;
}
+ return false;
}
/**
diff --git a/test/jdk/jb/java/awt/Toolkit/AWTThreadingTest.java b/test/jdk/jb/java/awt/Toolkit/AWTThreadingTest.java
index 2778c3eeb98..3f1c7e9abca 100644
--- a/test/jdk/jb/java/awt/Toolkit/AWTThreadingTest.java
+++ b/test/jdk/jb/java/awt/Toolkit/AWTThreadingTest.java
@@ -5,6 +5,7 @@ import java.util.Arrays;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
import java.util.function.Supplier;
import sun.lwawt.macosx.CThreading;
@@ -38,18 +39,24 @@ public class AWTThreadingTest {
testCase().
withCaption("certain threads superposition").
- withRunnable(AWTThreadingTest::test, false).
+ withRunnable(AWTThreadingTest::test1, false).
run();
testCase().
withCaption("random threads superposition").
- withRunnable(AWTThreadingTest::test, false).
+ withRunnable(AWTThreadingTest::test1, false).
+ run();
+
+ testCase().
+ withCaption("JBR-4362").
+ withRunnable(AWTThreadingTest::test2, false).
+ withCompletionTimeout(3).
run();
System.out.println("Test PASSED");
}
- static void test() {
+ static void test1() {
ITER_COUNTER.set(0);
var timer = new TestTimer(TIMEOUT_SECONDS * 3, TimeUnit.SECONDS);
@@ -124,6 +131,53 @@ public class AWTThreadingTest {
THREAD.start();
}
+ static void test2() {
+ var invocations = new CountDownLatch(1);
+ var invokeAndWaitCompleted = new AtomicBoolean(false);
+
+ var log = new Consumer<String>() {
+ public void accept(String msg) {
+ System.out.println(msg);
+ System.out.flush();
+ }
+ };
+
+ CThreading.executeOnAppKit(() -> {
+ log.accept("executeOnAppKit - entered");
+
+ //
+ // It's expected that LWCToolkit.invokeAndWait() does not exit before its invocation completes.
+ //
+ tryRun(() -> LWCToolkit.invokeAndWait(() -> {
+ log.accept("\tinvokeAndWait - entered");
+
+ AWTThreading.executeWaitToolkit(() -> {
+ log.accept("\t\texecuteWaitToolkit - entered");
+
+ LWCToolkit.performOnMainThreadAndWait(() -> log.accept("\t\t\tperformOnMainThreadAndWait - entered"));
+
+ log.accept("\t\t\tperformOnMainThreadAndWait - exited");
+ });
+
+ invokeAndWaitCompleted.set(true);
+ log.accept("\t\texecuteWaitToolkit - exited");
+ }, FRAME));
+
+ log.accept("\tinvokeAndWait - exited");
+
+ if (!invokeAndWaitCompleted.get()) {
+ TEST_CASE_RESULT.completeExceptionally(new Throwable("Premature exit from invokeAndWait"));
+ }
+
+ invocations.countDown();
+ });
+
+ await(invocations, TIMEOUT_SECONDS * 2);
+ log.accept("executeOnAppKit + await - exited");
+
+ TEST_CASE_RESULT.complete(true);
+ }
+
static void dumpAllThreads() {
Thread.getAllStackTraces().keySet().forEach(t -> {
System.out.printf("%s\t%s\t%d\t%s\n", t.getName(), t.getState(), t.getPriority(), t.isDaemon() ? "Daemon" : "Normal");
diff --git a/test/jdk/jb/java/awt/Toolkit/LWCToolkitInvokeAndWaitTest.java b/test/jdk/jb/java/awt/Toolkit/LWCToolkitInvokeAndWaitTest.java
index 53dfeb951bc..77dd2c35479 100644
--- a/test/jdk/jb/java/awt/Toolkit/LWCToolkitInvokeAndWaitTest.java
+++ b/test/jdk/jb/java/awt/Toolkit/LWCToolkitInvokeAndWaitTest.java
@@ -18,8 +18,8 @@ import static helper.ToolkitTestHelper.TestCase.*;
* @summary Tests different scenarios for LWCToolkit.invokeAndWait().
* @requires (os.family == "mac")
* @modules java.desktop/sun.lwawt.macosx java.desktop/sun.awt
- * @run main/othervm -Dsun.lwawt.macosx.LWCToolkit.invokeAndWait.disposeOnEDTFree=true LWCToolkitInvokeAndWaitTest
- * @run main/othervm -Dlog.level.FINER=true -Dsun.lwawt.macosx.LWCToolkit.invokeAndWait.disposeOnEDTFree=true LWCToolkitInvokeAndWaitTest
+ * @run main LWCToolkitInvokeAndWaitTest
+ * @run main/othervm -Dlog.level.FINER=true LWCToolkitInvokeAndWaitTest
* @author Anton Tarasov
*/
@SuppressWarnings("ConstantConditions")
@@ -32,6 +32,8 @@ public class LWCToolkitInvokeAndWaitTest {
static volatile CountDownLatch EDT_FAST_FREE_LATCH;
static {
+ System.setProperty("sun.lwawt.macosx.LWCToolkit.invokeAndWait.disposeOnEDTFree", "true");
+
AWTThreading.setAWTThreadingFactory(edt -> new AWTThreading(edt) {
@Override
public CompletableFuture<Void> onEventDispatchThreadFree(Runnable runnable) {
diff --git a/test/jdk/jb/java/awt/Toolkit/helper/ToolkitTestHelper.java b/test/jdk/jb/java/awt/Toolkit/helper/ToolkitTestHelper.java
index 510c293d658..3e8383a2edc 100644
--- a/test/jdk/jb/java/awt/Toolkit/helper/ToolkitTestHelper.java
+++ b/test/jdk/jb/java/awt/Toolkit/helper/ToolkitTestHelper.java
@@ -8,6 +8,8 @@ import sun.lwawt.macosx.LWCToolkit;
import javax.swing.*;
import javax.swing.Timer;
import java.awt.*;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
import java.util.Optional;
import java.util.Random;
import java.util.concurrent.Callable;
@@ -65,6 +67,7 @@ public class ToolkitTestHelper {
handler.uncaughtException(t, e);
});
+ CountDownLatch showLatch = new CountDownLatch(1);
tryRun(() -> EventQueue.invokeAndWait(() -> {
FRAME = new JFrame(testClass.getSimpleName());
LABEL = new JLabel("0");
@@ -75,8 +78,16 @@ public class ToolkitTestHelper {
FRAME.setLocationRelativeTo(null);
FRAME.setSize(200, 200);
FRAME.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+ FRAME.addComponentListener(new ComponentAdapter() {
+ @Override
+ public void componentShown(ComponentEvent e) {
+ showLatch.countDown();
+ }
+ });
FRAME.setVisible(true);
}));
+ //noinspection ResultOfMethodCallIgnored
+ tryRun(() -> showLatch.await(1, TimeUnit.SECONDS));
Timer timer = new Timer(100, e -> UPDATE_LABEL.run());
timer.setRepeats(true);
diff --git a/test/jdk/jbA11yProblemList.txt b/test/jdk/jbA11yProblemList.txt
index 86e550dd76f..a07167703da 100644
--- a/test/jdk/jbA11yProblemList.txt
+++ b/test/jdk/jbA11yProblemList.txt
@@ -1 +1,4 @@
-sanity/client/SwingSet/src/TreeDemoTest.java JBR-3389 macosx-all
+java/awt/Toolkit/LWCToolkitInvokeAndWaitTest.java nobug macosx-all,linux-all,windows-all
+java/awt/Toolkit/AWTThreadingTest.java nobug macosx-all,linux-all,windows-all
+java/awt/Toolkit/AWTThreadingCMenuTest.java nobug macosx-all,linux-all,windows-all
+sanity/client/SwingSet/src/TreeDemoTest.java JBR-3389 macosx-all