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