changeset 57777:6dbd8a434f44

8210231: Robot.delay() catches InterruptedException and prints stacktrace to stderr Reviewed-by: alanb, smarks
author serb
date Wed, 25 Dec 2019 14:17:57 +0300
parents 34f4782c0850
children 00eb693aee42
files src/java.desktop/share/classes/java/awt/Robot.java test/jdk/java/awt/Robot/Delay/InterruptOfDelay.java test/jdk/java/awt/Robot/Delay/MultiThreadedDelay.java
diffstat 3 files changed, 131 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.desktop/share/classes/java/awt/Robot.java	Wed Dec 25 10:15:32 2019 +0300
+++ b/src/java.desktop/share/classes/java/awt/Robot.java	Wed Dec 25 14:17:57 2019 +0300
@@ -642,20 +642,25 @@
 
     /**
      * Sleeps for the specified time.
-     * To catch any {@code InterruptedException}s that occur,
-     * {@code Thread.sleep()} may be used instead.
+     * <p>
+     * If the invoking thread is interrupted while waiting, then it will return
+     * immediately with the interrupt status set. If the interrupted status is
+     * already set, this method returns immediately with the interrupt status
+     * set.
      *
      * @param  ms time to sleep in milliseconds
-     * @throws IllegalArgumentException if {@code ms}
-     *         is not between 0 and 60,000 milliseconds inclusive
-     * @see java.lang.Thread#sleep
+     * @throws IllegalArgumentException if {@code ms} is not between {@code 0}
+     *         and {@code 60,000} milliseconds inclusive
      */
-    public synchronized void delay(int ms) {
+    public void delay(int ms) {
         checkDelayArgument(ms);
-        try {
-            Thread.sleep(ms);
-        } catch(InterruptedException ite) {
-            ite.printStackTrace();
+        Thread thread = Thread.currentThread();
+        if (!thread.isInterrupted()) {
+            try {
+                Thread.sleep(ms);
+            } catch (final InterruptedException ignored) {
+                thread.interrupt(); // Preserve interrupt status
+            }
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/Robot/Delay/InterruptOfDelay.java	Wed Dec 25 14:17:57 2019 +0300
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2019, 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.Robot;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+/**
+ * @test
+ * @key headful
+ * @bug 8210231
+ */
+public final class InterruptOfDelay {
+
+    static final class DormantThread extends Thread {
+
+        public void run() {
+            final PrintStream old = System.err;
+            final ByteArrayOutputStream err = new ByteArrayOutputStream();
+            System.setErr(new PrintStream(err));
+            try {
+                new Robot().delay(10000);
+            } catch (final Exception e) {
+                throw new RuntimeException(e);
+            } finally {
+                System.setErr(old);
+            }
+            if (!err.toString().isBlank()) {
+                throw new RuntimeException("Error stream is not empty: " + err);
+            }
+            if (!Thread.currentThread().isInterrupted()) {
+                throw new RuntimeException("Thread was not interrupted");
+            }
+        }
+    }
+
+    public static void main(final String args[]) throws Exception {
+        final Thread t = new DormantThread();
+        t.start();
+        Thread.sleep(1000);
+        t.interrupt();
+        t.join();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/Robot/Delay/MultiThreadedDelay.java	Wed Dec 25 14:17:57 2019 +0300
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2019, 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.Robot;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * @test
+ * @key headful
+ * @bug 8210231
+ */
+public final class MultiThreadedDelay {
+
+    private static volatile boolean complete;
+
+    public static void main(final String[] args) throws Exception {
+        CountDownLatch go = new CountDownLatch(1);
+        Robot robot = new Robot();
+        Thread bigDelay = new Thread(() -> {
+            go.countDown();
+            robot.delay(20000);
+            complete = true;
+        });
+        bigDelay.start();
+        go.await();
+        robot.delay(1000);
+        if (complete) {
+            throw new RuntimeException("Delay is too slow");
+        }
+        bigDelay.interrupt();
+    }
+}