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 abstract static class Fun {abstract void f() throws Throwable;} 140 }