Path: blob/master/test/jdk/java/nio/channels/FileChannel/ClosedByInterrupt.java
41154 views
/*1* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @bug 697900925* @summary Ensure ClosedByInterruptException is thrown when I/O operation26* interrupted by Thread.interrupt27* @key randomness28*/2930import java.io.*;31import java.util.Random;32import java.nio.ByteBuffer;33import java.nio.channels.*;3435public class ClosedByInterrupt {3637static final int K = 1024;38static final Random rand = new Random();3940static volatile boolean failed;4142public static void main(String[] args) throws Exception {43File f = File.createTempFile("blah", null);44f.deleteOnExit();4546// create 1MB file.47byte[] b = new byte[K*K];48rand.nextBytes(b);49ByteBuffer bb = ByteBuffer.wrap(b);50try (FileChannel fc = new FileOutputStream(f).getChannel()) {51while (bb.hasRemaining())52fc.write(bb);53}5455// test with 1-16 concurrent threads56for (int i=1; i<=16; i++) {57System.out.format("%d thread(s)%n", i);58test(f, i);59if (failed)60break;61}6263if (failed)64throw new RuntimeException("Test failed");65}6667/**68* Starts "nThreads" that do I/O on the given file concurrently. Continuously69* interrupts one of the threads to cause the file to be closed and70* ClosedByInterruptException to be thrown. The other threads should "fail" with71* ClosedChannelException (or the more specific AsynchronousCloseException).72*/73static void test(File f, int nThreads) throws Exception {74try (FileChannel fc = new RandomAccessFile(f, "rwd").getChannel()) {75Thread[] threads = new Thread[nThreads];7677// start threads78for (int i=0; i<nThreads; i++) {79boolean interruptible = (i==0);80ReaderWriter task = new ReaderWriter(fc, interruptible);81Thread t = new Thread(task);82t.start();83threads[i] = t;84}8586// give time for threads to start87Thread.sleep(500 + rand.nextInt(1000));8889// interrupt thread until channel is closed90while (fc.isOpen()) {91threads[0].interrupt();92Thread.sleep(rand.nextInt(50));93}9495// wait for test to finish96for (int i=0; i<nThreads; i++) {97threads[i].join();98}99}100}101102/**103* A task that continuously reads or writes to random areas of a file104* until the channel is closed. An "interruptible" task expects the105* channel to be closed by an interupt, a "non-interruptible" thread106* does not.107*/108static class ReaderWriter implements Runnable {109final FileChannel fc;110final boolean interruptible;111final boolean writer;112113ReaderWriter(FileChannel fc, boolean interruptible) {114this.fc = fc;115this.interruptible = interruptible;116this.writer = rand.nextBoolean();117}118119public void run() {120ByteBuffer bb = ByteBuffer.allocate(K);121if (writer)122rand.nextBytes(bb.array());123124try {125for (;;) {126long position = rand.nextInt(K*K - bb.capacity());127if (writer) {128bb.position(0).limit(bb.capacity());129fc.write(bb, position);130} else {131bb.clear();132fc.read(bb, position);133}134if (!interruptible) {135// give the interruptible thread a chance136try {137Thread.sleep(rand.nextInt(50));138} catch (InterruptedException e) {139unexpected(e);140}141}142}143} catch (ClosedByInterruptException e) {144if (interruptible) {145if (Thread.interrupted()) {146expected(e + " thrown and interrupt status set");147} else {148unexpected(e + " thrown but interrupt status not set");149}150} else {151unexpected(e);152}153} catch (ClosedChannelException e) {154if (interruptible) {155unexpected(e);156} else {157expected(e);158}159} catch (Exception e) {160unexpected(e);161}162}163}164165static void expected(Exception e) {166System.out.format("%s (expected)%n", e);167}168169static void expected(String msg) {170System.out.format("%s (expected)%n", msg);171}172173static void unexpected(Exception e) {174System.err.format("%s (not expected)%n", e);175failed = true;176}177178static void unexpected(String msg) {179System.err.println(msg);180failed = true;181}182}183184185