DoneTimedGetLoops.java revision 12745:f068a4ffddd2
1/*
2 * Copyright (c) 2012, 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 * Written by Martin Buchholz with assistance from members of JCP JSR-166
26 * Expert Group and released to the public domain, as explained at
27 * http://creativecommons.org/publicdomain/zero/1.0/
28 */
29
30/*
31 * @test
32 * @run main DoneTimedGetLoops 300
33 * @summary isDone returning true guarantees that subsequent timed get
34 * will never throw TimeoutException.
35 */
36
37import java.util.*;
38import java.util.concurrent.*;
39import java.util.concurrent.atomic.*;
40
41@SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
42public class DoneTimedGetLoops {
43    final long testDurationMillisDefault = 10L * 1000L;
44    final long testDurationMillis;
45
46    static class PublicFutureTask extends FutureTask<Boolean> {
47        static final Runnable noop = new Runnable() { public void run() {} };
48        PublicFutureTask() { super(noop, null); }
49        public void set(Boolean v) { super.set(v); }
50        public void setException(Throwable t) { super.setException(t); }
51    }
52
53    DoneTimedGetLoops(String[] args) {
54        testDurationMillis = (args.length > 0) ?
55            Long.valueOf(args[0]) : testDurationMillisDefault;
56    }
57
58    void test(String[] args) throws Throwable {
59        final long testDurationNanos = testDurationMillis * 1000L * 1000L;
60        final long quittingTimeNanos = System.nanoTime() + testDurationNanos;
61        final long timeoutMillis = 10L * 1000L;
62
63        final AtomicReference<PublicFutureTask> normalRef
64            = new AtomicReference<PublicFutureTask>();
65        final AtomicReference<PublicFutureTask> abnormalRef
66            = new AtomicReference<PublicFutureTask>();
67
68        final Throwable throwable = new Throwable();
69
70        abstract class CheckedThread extends Thread {
71            CheckedThread(String name) {
72                super(name);
73                setDaemon(true);
74                start();
75            }
76            /** Polls for quitting time. */
77            protected boolean quittingTime() {
78                return System.nanoTime() - quittingTimeNanos > 0;
79            }
80            /** Polls occasionally for quitting time. */
81            protected boolean quittingTime(long i) {
82                return (i % 1024) == 0 && quittingTime();
83            }
84            protected abstract void realRun() throws Exception;
85            public void run() {
86                try { realRun(); } catch (Throwable t) { unexpected(t); }
87            }
88        }
89
90        Thread setter = new CheckedThread("setter") {
91            protected void realRun() {
92                while (! quittingTime()) {
93                    PublicFutureTask future = new PublicFutureTask();
94                    normalRef.set(future);
95                    future.set(Boolean.TRUE);
96                }}};
97
98        Thread setterException = new CheckedThread("setterException") {
99            protected void realRun() {
100                while (! quittingTime()) {
101                    PublicFutureTask future = new PublicFutureTask();
102                    abnormalRef.set(future);
103                    future.setException(throwable);
104                }}};
105
106        Thread doneTimedGetNormal = new CheckedThread("doneTimedGetNormal") {
107            protected void realRun() throws Exception {
108                while (! quittingTime()) {
109                    PublicFutureTask future = normalRef.get();
110                    if (future != null) {
111                        while (!future.isDone())
112                            ;
113                        check(future.get(0L, TimeUnit.HOURS) == Boolean.TRUE);
114                    }}}};
115
116        Thread doneTimedGetAbnormal = new CheckedThread("doneTimedGetAbnormal") {
117            protected void realRun() throws Exception {
118                while (! quittingTime()) {
119                    PublicFutureTask future = abnormalRef.get();
120                    if (future != null) {
121                        while (!future.isDone())
122                            ;
123                        try { future.get(0L, TimeUnit.HOURS); fail(); }
124                        catch (ExecutionException t) {
125                            check(t.getCause() == throwable);
126                        }
127                    }}}};
128
129        for (Thread thread : new Thread[] {
130                 setter,
131                 setterException,
132                 doneTimedGetNormal,
133                 doneTimedGetAbnormal }) {
134            thread.join(timeoutMillis + testDurationMillis);
135            if (thread.isAlive()) {
136                System.err.printf("Hung thread: %s%n", thread.getName());
137                failed++;
138                for (StackTraceElement e : thread.getStackTrace())
139                    System.err.println(e);
140                // Kludge alert
141                thread.stop();
142                thread.join(timeoutMillis);
143            }
144        }
145    }
146
147    //--------------------- Infrastructure ---------------------------
148    volatile int passed = 0, failed = 0;
149    void pass() {passed++;}
150    void fail() {failed++; Thread.dumpStack();}
151    void fail(String msg) {System.err.println(msg); fail();}
152    void unexpected(Throwable t) {failed++; t.printStackTrace();}
153    void check(boolean cond) {if (cond) pass(); else fail();}
154    void equal(Object x, Object y) {
155        if (x == null ? y == null : x.equals(y)) pass();
156        else fail(x + " not equal to " + y);}
157    public static void main(String[] args) throws Throwable {
158        new DoneTimedGetLoops(args).instanceMain(args);}
159    public void instanceMain(String[] args) throws Throwable {
160        try {test(args);} catch (Throwable t) {unexpected(t);}
161        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
162        if (failed > 0) throw new AssertionError("Some tests failed");}
163}
164