1 /*
2  * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /**
25  * @test
26  * @bug 8167108 8266130
27  * @summary Stress test java.lang.Thread.isInterrupted() at thread exit.
28  * @run main/othervm IsInterruptedAtExit
29  */
30 
31 import java.util.concurrent.CountDownLatch;
32 
33 public class IsInterruptedAtExit extends Thread {
34     private final static int DEF_TIME_MAX = 30;  // default max # secs to test
35     private final static String PROG_NAME = "IsInterruptedAtExit";
36 
37     public CountDownLatch exitSyncObj = new CountDownLatch(1);
38     public CountDownLatch startSyncObj = new CountDownLatch(1);
39 
40     @Override
run()41     public void run() {
42         // Tell main thread we have started.
43         startSyncObj.countDown();
44         try {
45             // Wait for main thread to tell us to race to the exit.
46             exitSyncObj.await();
47         } catch (InterruptedException e) {
48             throw new RuntimeException("Unexpected: " + e);
49         }
50     }
51 
main(String[] args)52     public static void main(String[] args) {
53         int timeMax = 0;
54         if (args.length == 0) {
55             timeMax = DEF_TIME_MAX;
56         } else {
57             try {
58                 timeMax = Integer.parseUnsignedInt(args[0]);
59             } catch (NumberFormatException nfe) {
60                 System.err.println("'" + args[0] + "': invalid timeMax value.");
61                 usage();
62             }
63         }
64 
65         System.out.println("About to execute for " + timeMax + " seconds.");
66 
67         long count = 0;
68         long start_time = System.currentTimeMillis();
69         while (System.currentTimeMillis() < start_time + (timeMax * 1000)) {
70             count++;
71 
72             IsInterruptedAtExit thread = new IsInterruptedAtExit();
73             thread.start();
74             try {
75                 // Wait for the worker thread to get going.
76                 thread.startSyncObj.await();
77                 // Tell the worker thread to race to the exit and the
78                 // Thread.isInterrupted() calls will come in during
79                 // thread exit.
80                 thread.exitSyncObj.countDown();
81                 while (true) {
82                     thread.isInterrupted();
83 
84                     if (!thread.isAlive()) {
85                         // Done with Thread.isInterrupted() calls since
86                         // thread is not alive.
87                         break;
88                     }
89                 }
90             } catch (InterruptedException e) {
91                 throw new Error("Unexpected: " + e);
92             }
93 
94             try {
95                 thread.join();
96             } catch (InterruptedException e) {
97                 throw new Error("Unexpected: " + e);
98             }
99             thread.isInterrupted();
100         }
101 
102         System.out.println("Executed " + count + " loops in " + timeMax +
103                            " seconds.");
104 
105         String cmd = System.getProperty("sun.java.command");
106         if (cmd != null && !cmd.startsWith("com.sun.javatest.regtest.agent.MainWrapper")) {
107             // Exit with success in a non-JavaTest environment:
108             System.exit(0);
109         }
110     }
111 
usage()112     public static void usage() {
113         System.err.println("Usage: " + PROG_NAME + " [time_max]");
114         System.err.println("where:");
115         System.err.println("    time_max  max looping time in seconds");
116         System.err.println("              (default is " + DEF_TIME_MAX +
117                            " seconds)");
118         System.exit(1);
119     }
120 }
121