1 /*
2 * Copyright (c) 2006, 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 6384064
27 * @summary Check proper handling of interrupts
28 * @run main/othervm -XX:-UseVMInterruptibleIO Interrupt
29 * @author Martin Buchholz
30 */
31
32 import java.util.*;
33 import java.util.concurrent.*;
34 import static java.util.concurrent.TimeUnit.*;
35
36 public class Interrupt {
37
38 static void checkInterrupted0(Iterable<Fun> fs, Executor ex) {
39 for (Fun f : fs) {
40 try {
41 ex.execute(new Runnable() {
42 final Thread thisThread = Thread.currentThread();
43 public void run() { thisThread.interrupt(); }});
44 f.f();
45 fail("Expected InterruptedException not thrown");
46 } catch (InterruptedException e) {
47 check(! Thread.interrupted());
48 } catch (Throwable t) { unexpected(t); }
49 }
50 }
51
52 static void checkInterrupted(Iterable<Fun> fs) {
53 final Executor immediateExecutor = new Executor() {
54 public void execute(Runnable r) {
55 r.run(); }};
56 final ScheduledThreadPoolExecutor stpe
57 = new ScheduledThreadPoolExecutor(1);
58 final Executor delayedExecutor = new Executor() {
59 public void execute(Runnable r) {
60 stpe.schedule(r, 20, MILLISECONDS); }};
61 checkInterrupted0(fs, immediateExecutor);
62 checkInterrupted0(fs, delayedExecutor);
63 stpe.shutdown();
64 }
65
66 static void testQueue(final BlockingQueue<Object> q) {
67 try {
68 final BlockingDeque<Object> deq =
69 (q instanceof BlockingDeque<?>) ?
70 (BlockingDeque<Object>) q : null;
71 q.clear();
72 List<Fun> fs = new ArrayList<Fun>();
73 fs.add(new Fun() { void f() throws Throwable
74 { q.take(); }});
75 fs.add(new Fun() { void f() throws Throwable
76 { q.poll(60, SECONDS); }});
77 if (deq != null) {
78 fs.add(new Fun() { void f() throws Throwable
79 { deq.takeFirst(); }});
80 fs.add(new Fun() { void f() throws Throwable
81 { deq.takeLast(); }});
82 fs.add(new Fun() { void f() throws Throwable
83 { deq.pollFirst(7, SECONDS); }});
84 fs.add(new Fun() { void f() throws Throwable
85 { deq.pollLast(7, SECONDS); }});
86 }
87
88 checkInterrupted(fs);
89
90 // fill q to capacity, to ensure insertions will block
91 while (q.remainingCapacity() > 0)
92 try { q.put(1); }
93 catch (Throwable t) { unexpected(t); }
94
95 fs.clear();
96 fs.add(new Fun() { void f() throws Throwable
97 { q.put(1); }});
98 fs.add(new Fun() { void f() throws Throwable
99 { q.offer(1, 7, SECONDS); }});
100 if (deq != null) {
101 fs.add(new Fun() { void f() throws Throwable
102 { deq.putFirst(1); }});
103 fs.add(new Fun() { void f() throws Throwable
104 { deq.putLast(1); }});
105 fs.add(new Fun() { void f() throws Throwable
106 { deq.offerFirst(1, 7, SECONDS); }});
107 fs.add(new Fun() { void f() throws Throwable
108 { deq.offerLast(1, 7, SECONDS); }});
109 }
110 checkInterrupted(fs);
111 } catch (Throwable t) {
112 System.out.printf("Failed: %s%n", q.getClass().getSimpleName());
113 unexpected(t);
114 }
115 }
116
117 private static void realMain(final String[] args) throws Throwable {
118 testQueue(new SynchronousQueue<Object>());
119 testQueue(new ArrayBlockingQueue<Object>(1,false));
120 testQueue(new ArrayBlockingQueue<Object>(1,true));
121 testQueue(new LinkedBlockingQueue<Object>(1));
122 testQueue(new LinkedBlockingDeque<Object>(1));
123 }
124
125 //--------------------- Infrastructure ---------------------------
126 static volatile int passed = 0, failed = 0;
127 static void pass() {passed++;}
128 static void fail() {failed++; Thread.dumpStack();}
129 static void fail(String msg) {System.out.println(msg); fail();}
130 static void unexpected(Throwable t) {failed++; t.printStackTrace();}
131 static void check(boolean cond) {if (cond) pass(); else fail();}
132 static void equal(Object x, Object y) {
133 if (x == null ? y == null : x.equals(y)) pass();
134 else fail(x + " not equal to " + y);}
135 public static void main(String[] args) throws Throwable {
136 try {realMain(args);} catch (Throwable t) {unexpected(t);}
137 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
138 if (failed > 0) throw new AssertionError("Some tests failed");}
139 private static abstract class Fun {abstract void f() throws Throwable;}
140 }
--- EOF ---