6050N/A/*
6050N/A * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
6050N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6050N/A *
6050N/A * This code is free software; you can redistribute it and/or modify it
6050N/A * under the terms of the GNU General Public License version 2 only, as
6050N/A * published by the Free Software Foundation.
6050N/A *
6050N/A * This code is distributed in the hope that it will be useful, but WITHOUT
6050N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6050N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6050N/A * version 2 for more details (a copy is included in the LICENSE file that
6050N/A * accompanied this code).
6050N/A *
6050N/A * You should have received a copy of the GNU General Public License version
6050N/A * 2 along with this work; if not, write to the Free Software Foundation,
6050N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
6050N/A *
6050N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
6050N/A * or visit www.oracle.com if you need additional information or have any
6050N/A * questions.
6050N/A */
6050N/A
6050N/A/* @test
6050N/A * @bug 8012019
6050N/A * @summary Tests interruption of threads doing position-based read methods in
6050N/A * an attempt to provoke a deadlock between position sensitive and position
6050N/A * insensitive methods
6050N/A */
6050N/Aimport java.nio.ByteBuffer;
6050N/Aimport java.nio.channels.*;
6050N/Aimport java.nio.file.*;
6050N/Aimport static java.nio.file.StandardOpenOption.*;
6050N/A
6050N/Apublic class InterruptDeadlock {
6050N/A
6050N/A /**
6050N/A * A thread that continuously reads from a FileChannel with
6050N/A * read(ByteBuffer,long). The thread terminates when interrupted and/or
6050N/A * the FileChannel is closed.
6050N/A */
6050N/A static class Reader extends Thread {
6050N/A final FileChannel fc;
6050N/A volatile Exception exception;
6050N/A
6050N/A Reader(FileChannel fc) {
6050N/A this.fc = fc;
6050N/A }
6050N/A
6050N/A @Override
6050N/A public void run() {
6050N/A ByteBuffer bb = ByteBuffer.allocate(1024);
6050N/A try {
6050N/A long pos = 0L;
6050N/A for (;;) {
6050N/A bb.clear();
6050N/A int n = fc.read(bb, pos);
6050N/A if (n > 0)
6050N/A pos += n;
6050N/A // fc.size is important here as it is position sensitive
6050N/A if (pos > fc.size())
6050N/A pos = 0L;
6050N/A }
6050N/A } catch (ClosedChannelException x) {
6050N/A System.out.println(x.getClass() + " (expected)");
6050N/A } catch (Exception unexpected) {
6050N/A this.exception = unexpected;
6050N/A }
6050N/A }
6050N/A
6050N/A Exception exception() {
6050N/A return exception;
6050N/A }
6050N/A
6050N/A static Reader startReader(FileChannel fc) {
6050N/A Reader r = new Reader(fc);
6050N/A r.start();
6050N/A return r;
6050N/A }
6050N/A }
6050N/A
6050N/A // the number of reader threads to start
6050N/A private static final int READER_COUNT = 4;
6050N/A
6050N/A public static void main(String[] args) throws Exception {
6050N/A Path file = Paths.get("data.txt");
6050N/A try (FileChannel fc = FileChannel.open(file, CREATE, TRUNCATE_EXISTING, WRITE)) {
6050N/A fc.position(1024L * 1024L);
6050N/A fc.write(ByteBuffer.wrap(new byte[1]));
6050N/A }
6050N/A
6050N/A Reader[] readers = new Reader[READER_COUNT];
6050N/A
6050N/A for (int i=1; i<=20; i++) {
6050N/A System.out.format("Iteration: %s%n", i);
6050N/A
6050N/A try (FileChannel fc = FileChannel.open(file)) {
6050N/A boolean failed = false;
6050N/A
6050N/A // start reader threads
6050N/A for (int j=0; j<READER_COUNT; j++) {
6050N/A readers[j] = Reader.startReader(fc);
6050N/A }
6050N/A
6050N/A // give readers a bit of time to get started (not strictly required)
6050N/A Thread.sleep(100);
6050N/A
6050N/A // interrupt and wait for the readers to terminate
6050N/A for (Reader r: readers) {
6050N/A r.interrupt();
6050N/A }
6050N/A for (Reader r: readers) {
6050N/A try {
6050N/A r.join(10000);
6050N/A Exception e = r.exception();
6050N/A if (e != null) {
6050N/A System.err.println("Reader thread failed with: " + e);
6050N/A failed = true;
6050N/A }
6050N/A } catch (InterruptedException x) {
6050N/A System.err.println("Reader thread did not terminte");
6050N/A failed = true;
6050N/A }
6050N/A }
6050N/A
6050N/A // the channel should not be open at this point
6050N/A if (fc.isOpen()) {
6050N/A System.err.println("FileChannel was not closed");
6050N/A failed = true;
6050N/A }
6050N/A
6050N/A if (failed)
6050N/A throw new RuntimeException("Test failed - see log for details");
6050N/A }
6050N/A }
6050N/A }
6050N/A}