Path: blob/master/test/jdk/java/nio/channels/SocketChannel/AsyncCloseChannel.java
41154 views
/*1* Copyright (c) 2006, 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 6285901 650108925* @summary Check no data is written to wrong socket channel during async closing.26*/2728import java.io.IOException;29import java.net.InetAddress;30import java.net.InetSocketAddress;31import java.net.ServerSocket;32import java.net.Socket;33import java.nio.ByteBuffer;34import java.nio.channels.ClosedChannelException;35import java.nio.channels.SocketChannel;3637public class AsyncCloseChannel {38static volatile boolean failed = false;39static volatile boolean keepGoing = true;40static int maxAcceptCount = 100;41static volatile int acceptCount = 0;42static int sensorPort;43static int targetPort;4445public static void main(String args[]) throws Exception {46if (System.getProperty("os.name").startsWith("Windows")) {47System.err.println("WARNING: Still does not work on Windows!");48return;49}50Thread ss = new SensorServer(); ss.start();51Thread ts = new TargetServer(); ts.start();5253sensorPort = ((ServerThread)ss).server.getLocalPort();54targetPort = ((ServerThread)ts).server.getLocalPort();5556Thread sc = new SensorClient(); sc.start();57Thread tc = new TargetClient(); tc.start();5859while(acceptCount < maxAcceptCount && !failed) {60Thread.sleep(10);61}62keepGoing = false;63try {64ss.interrupt();65ts.interrupt();66sc.interrupt();67tc.interrupt();68} catch (Exception e) {}69if (failed)70throw new RuntimeException("AsyncCloseChannel2 failed after <"71+ acceptCount + "> times of accept!");72}7374static class SensorServer extends ServerThread {75public void runEx() throws Exception {76while(keepGoing) {77try {78final Socket s = server.accept();79new Thread() {80public void run() {81try {82int c = s.getInputStream().read();83if(c != -1) {84// No data is ever written to the peer's socket!85System.err.println("Oops: read a character: "86+ (char) c);87failed = true;88}89} catch (IOException ex) {90ex.printStackTrace();91} finally {92closeIt(s);93}94}95}.start();96} catch (IOException ex) {97System.err.println("Exception on sensor server " + ex.getMessage());98}99}100}101}102103static class TargetServer extends ServerThread {104public void runEx() throws Exception {105while (keepGoing) {106try {107final Socket s = server.accept();108acceptCount++;109new Thread() {110public void run() {111boolean empty = true;112try {113while (keepGoing) {114int c = s.getInputStream().read();115if(c == -1) {116if(!empty)117break;118}119empty = false;120}121} catch (IOException ex) {122ex.printStackTrace();123} finally {124closeIt(s);125}126}127}.start();128} catch (IOException ex) {129System.err.println("Exception on target server " + ex.getMessage());130}131}132}133}134135static class SensorClient extends Thread {136private static boolean wake;137private static SensorClient theClient;138public void run() {139while (keepGoing) {140Socket s = null;141try {142s = new Socket();143synchronized(this) {144while(!wake && keepGoing) {145try {146wait();147} catch (InterruptedException ex) { }148}149wake = false;150}151s.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), sensorPort));152try {153Thread.sleep(10);154} catch (InterruptedException ex) { }155} catch (IOException ex) {156System.err.println("Exception on sensor client " + ex.getMessage());157} finally {158if(s != null) {159try {160s.close();161} catch(IOException ex) { ex.printStackTrace();}162}163}164}165}166167public SensorClient() {168theClient = this;169}170171public static void wakeMe() {172synchronized(theClient) {173wake = true;174theClient.notify();175}176}177}178179static class TargetClient extends Thread {180volatile boolean ready = false;181public void run() {182while(keepGoing) {183try {184final SocketChannel s = SocketChannel.open(185new InetSocketAddress(InetAddress.getLoopbackAddress(), targetPort));186s.finishConnect();187s.socket().setSoLinger(false, 0);188ready = false;189Thread t = new Thread() {190public void run() {191ByteBuffer b = ByteBuffer.allocate(1);192try {193for(;;) {194b.clear();195b.put((byte) 'A');196b.flip();197s.write(b);198ready = true;199}200} catch (IOException ex) {201if(!(ex instanceof ClosedChannelException))202System.err.println("Exception in target client child "203+ ex.toString());204}205}206};207t.start();208while(!ready && keepGoing) {209try {210Thread.sleep(10);211} catch (InterruptedException ex) {}212}213s.close();214SensorClient.wakeMe();215t.join();216} catch (IOException ex) {217System.err.println("Exception in target client parent "218+ ex.getMessage());219} catch (InterruptedException ex) {}220}221}222}223224static abstract class ServerThread extends Thread {225ServerSocket server;226public ServerThread() {227super();228try {229server = new ServerSocket(0);230} catch (IOException ex) {231ex.printStackTrace();232}233}234235public void interrupt() {236super.interrupt();237if (server != null) {238try {239server.close();240} catch (IOException ex) {241ex.printStackTrace();242}243}244}245public void run() {246try {247runEx();248} catch (Exception ex) {249ex.printStackTrace();250}251}252253abstract void runEx() throws Exception;254}255256public static void closeIt(Socket s) {257try {258if(s != null)259s.close();260} catch (IOException ex) { }261}262}263264265