Path: blob/master/test/jdk/java/nio/channels/FileChannel/InterruptDeadlock.java
41154 views
/*1* Copyright (c) 2017, 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 801201925* @summary Tests interruption of threads doing position-based read methods in26* an attempt to provoke a deadlock between position sensitive and position27* insensitive methods28*/29import java.nio.ByteBuffer;30import java.nio.channels.*;31import java.nio.file.*;32import static java.nio.file.StandardOpenOption.*;3334public class InterruptDeadlock {3536/**37* A thread that continuously reads from a FileChannel with38* read(ByteBuffer,long). The thread terminates when interrupted and/or39* the FileChannel is closed.40*/41static class Reader extends Thread {42final FileChannel fc;43volatile Exception exception;4445Reader(FileChannel fc) {46this.fc = fc;47}4849@Override50public void run() {51ByteBuffer bb = ByteBuffer.allocate(1024);52try {53long pos = 0L;54for (;;) {55bb.clear();56int n = fc.read(bb, pos);57if (n > 0)58pos += n;59// fc.size is important here as it is position sensitive60if (pos >= fc.size())61pos = 0L;62}63} catch (ClosedChannelException x) {64System.out.println(x.getClass() + " (expected)");65} catch (Exception unexpected) {66this.exception = unexpected;67}68}6970Exception exception() {71return exception;72}7374static Reader startReader(FileChannel fc) {75Reader r = new Reader(fc);76r.start();77return r;78}79}8081// the number of reader threads to start82private static final int READER_COUNT = 4;8384public static void main(String[] args) throws Exception {85Path file = Paths.get("data.txt");86try (FileChannel fc = FileChannel.open(file, CREATE, TRUNCATE_EXISTING, WRITE)) {87fc.position(1024L * 1024L);88fc.write(ByteBuffer.wrap(new byte[1]));89}9091Reader[] readers = new Reader[READER_COUNT];9293for (int i=1; i<=20; i++) {94System.out.format("Iteration: %s%n", i);9596try (FileChannel fc = FileChannel.open(file)) {97boolean failed = false;9899// start reader threads100for (int j=0; j<READER_COUNT; j++) {101readers[j] = Reader.startReader(fc);102}103104// give readers a bit of time to get started (not strictly required)105Thread.sleep(100);106107// interrupt and wait for the readers to terminate108for (Reader r: readers) {109r.interrupt();110}111for (Reader r: readers) {112try {113r.join(10000);114Exception e = r.exception();115if (e != null) {116System.err.println("Reader thread failed with: " + e);117failed = true;118}119} catch (InterruptedException x) {120System.err.println("Reader thread did not terminte");121failed = true;122}123}124125// the channel should not be open at this point126if (fc.isOpen()) {127System.err.println("FileChannel was not closed");128failed = true;129}130131if (failed)132throw new RuntimeException("Test failed - see log for details");133}134}135}136}137138139