Path: blob/master/test/jdk/java/nio/channels/etc/AdaptorCloseAndInterrupt.java
41153 views
/*1* Copyright (c) 2012, 2019, 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 7184932 823267325* @summary Test asynchronous close and interrupt of timed socket adapter methods26* @key randomness intermittent27*/2829import java.io.*;30import java.nio.*;31import java.nio.channels.*;32import java.nio.channels.spi.AbstractSelectableChannel;33import java.net.*;34import java.util.concurrent.Callable;35import java.util.concurrent.Executors;36import java.util.concurrent.ScheduledExecutorService;37import java.util.concurrent.TimeUnit;38import java.util.concurrent.atomic.AtomicBoolean;39import java.util.Random;404142public class AdaptorCloseAndInterrupt {43private static final ScheduledExecutorService pool =44Executors.newScheduledThreadPool(1);45final ServerSocketChannel listener;46final DatagramChannel peer;47final int port;4849final AtomicBoolean isClosed = new AtomicBoolean();50final AtomicBoolean isInterrupted = new AtomicBoolean();5152public AdaptorCloseAndInterrupt() {53listener = null;54peer = null;55port = -1;56}5758public AdaptorCloseAndInterrupt(ServerSocketChannel listener) {59this.listener = listener;60this.port = listener.socket().getLocalPort();61this.peer = null;62}6364public AdaptorCloseAndInterrupt(DatagramChannel listener) {65this.peer = listener;66this.port = peer.socket().getLocalPort();67this.listener = null;68}6970public static void main(String args[]) throws Exception {71try {72try (ServerSocketChannel listener = ServerSocketChannel.open()) {73listener.socket().bind(null);74new AdaptorCloseAndInterrupt(listener).scReadAsyncClose();75new AdaptorCloseAndInterrupt(listener).scReadAsyncInterrupt();76}7778try (DatagramChannel peer = DatagramChannel.open()) {79peer.socket().bind(null);80new AdaptorCloseAndInterrupt(peer).dcReceiveAsyncClose(0);81new AdaptorCloseAndInterrupt(peer).dcReceiveAsyncClose(30_000);82new AdaptorCloseAndInterrupt(peer).dcReceiveAsyncInterrupt(0);83new AdaptorCloseAndInterrupt(peer).dcReceiveAsyncInterrupt(30_000);84}8586new AdaptorCloseAndInterrupt().ssAcceptAsyncClose();87new AdaptorCloseAndInterrupt().ssAcceptAsyncInterrupt();88} finally {89pool.shutdown();90}91System.out.println("Test Passed");92}9394void scReadAsyncClose() throws IOException {95try {96SocketChannel sc = SocketChannel.open(new InetSocketAddress(97InetAddress.getLoopbackAddress(), port));98sc.socket().setSoTimeout(30*1000);99100doAsyncClose(sc);101102try {103sc.socket().getInputStream().read(new byte[100]);104System.err.format("close() was invoked: %s%n", isClosed.get());105throw new RuntimeException("read should not have completed");106} catch (ClosedChannelException expected) {}107108if (!sc.socket().isClosed())109throw new RuntimeException("socket is not closed");110} finally {111// accept connection and close it.112listener.accept().close();113}114}115116void scReadAsyncInterrupt() throws IOException {117try {118final SocketChannel sc = SocketChannel.open(new InetSocketAddress(119InetAddress.getLoopbackAddress(), port));120sc.socket().setSoTimeout(30*1000);121122doAsyncInterrupt();123124try {125sc.socket().getInputStream().read(new byte[100]);126throw new RuntimeException("read should not have completed");127} catch (ClosedByInterruptException expected) {128System.out.format("interrupt() was invoked: %s%n",129isInterrupted.get());130System.out.format("scReadAsyncInterrupt was interrupted: %s%n",131Thread.currentThread().interrupted());132}133134if (!sc.socket().isClosed())135throw new RuntimeException("socket is not closed");136} finally {137// accept connection and close it.138listener.accept().close();139}140}141142void dcReceiveAsyncClose(int timeout) throws IOException {143DatagramChannel dc = DatagramChannel.open();144dc.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), port));145dc.socket().setSoTimeout(timeout);146147doAsyncClose(dc);148149try {150dc.socket().receive(new DatagramPacket(new byte[100], 100));151System.err.format("close() was invoked: %s%n", isClosed.get());152throw new RuntimeException("receive should not have completed");153} catch (SocketException expected) { }154155if (!dc.socket().isClosed())156throw new RuntimeException("socket is not closed");157}158159void dcReceiveAsyncInterrupt(int timeout) throws IOException {160DatagramChannel dc = DatagramChannel.open();161dc.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), port));162dc.socket().setSoTimeout(timeout);163164doAsyncInterrupt();165166try {167dc.socket().receive(new DatagramPacket(new byte[100], 100));168throw new RuntimeException("receive should not have completed");169} catch (SocketException expected) {170System.out.format("interrupt() was invoked: %s%n",171isInterrupted.get());172System.out.format("dcReceiveAsyncInterrupt was interrupted: %s%n",173Thread.currentThread().interrupted());174} catch (SocketTimeoutException unexpected) {175System.err.format("Receive thread interrupt invoked: %s%n",176isInterrupted.get());177System.err.format("Receive thread was interrupted: %s%n",178Thread.currentThread().isInterrupted());179throw unexpected;180}181182if (!dc.socket().isClosed())183throw new RuntimeException("socket is not closed");184}185186void ssAcceptAsyncClose() throws IOException {187ServerSocketChannel ssc = ServerSocketChannel.open();188ssc.socket().bind(null);189ssc.socket().setSoTimeout(30*1000);190191doAsyncClose(ssc);192193try {194ssc.socket().accept();195System.err.format("close() was invoked: %s%n", isClosed.get());196throw new RuntimeException("accept should not have completed");197} catch (ClosedChannelException expected) {}198199if (!ssc.socket().isClosed())200throw new RuntimeException("socket is not closed");201}202203void ssAcceptAsyncInterrupt() throws IOException {204ServerSocketChannel ssc = ServerSocketChannel.open();205ssc.socket().bind(null);206ssc.socket().setSoTimeout(30*1000);207208doAsyncInterrupt();209210try {211ssc.socket().accept();212throw new RuntimeException("accept should not have completed");213} catch (ClosedByInterruptException expected) {214System.out.format("interrupt() was invoked: %s%n",215isInterrupted.get());216System.out.format("ssAcceptAsyncInterrupt was interrupted: %s%n",217Thread.currentThread().interrupted());218}219220if (!ssc.socket().isClosed())221throw new RuntimeException("socket is not closed");222}223224void doAsyncClose(final AbstractSelectableChannel sc) {225AdaptorCloseAndInterrupt.pool.schedule(new Callable<Void>() {226public Void call() throws Exception {227sc.close();228isClosed.set(true);229return null;230}231}, new Random().nextInt(1000), TimeUnit.MILLISECONDS);232}233234void doAsyncInterrupt() {235final Thread current = Thread.currentThread();236AdaptorCloseAndInterrupt.pool.schedule(new Callable<Void>() {237public Void call() throws Exception {238current.interrupt();239isInterrupted.set(true);240return null;241}242}, new Random().nextInt(1000), TimeUnit.MILLISECONDS);243}244245}246247248