Path: blob/master/test/jdk/java/net/Socket/SocketReadInterruptTest.java
41152 views
/*1* Copyright (c) 2020, 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/**24* @test25* @bug 823785826* @summary PlainSocketImpl.socketAccept() handles EINTR incorrectly27* @requires (os.family != "windows")28* @compile NativeThread.java29* @run main/othervm/native -Djdk.net.usePlainSocketImpl=true SocketReadInterruptTest 2000 300030* @run main/othervm/native SocketReadInterruptTest 2000 300031* @run main/othervm/native -Djdk.net.usePlainSocketImpl=true SocketReadInterruptTest 2000 032* @run main/othervm/native SocketReadInterruptTest 2000 033*/34import java.io.IOException;35import java.io.InputStream;36import java.io.OutputStream;37import java.net.InetAddress;38import java.net.ServerSocket;3940import java.net.*;41import java.util.concurrent.Callable;42import java.util.concurrent.ExecutorService;43import java.util.concurrent.Executors;44import java.util.concurrent.Future;4546public class SocketReadInterruptTest {4748public static void main(String[] args) throws Exception {49System.loadLibrary("NativeThread");50ExecutorService executor = Executors.newFixedThreadPool(2);51InetAddress loopback = InetAddress.getLoopbackAddress();5253try ( ServerSocket ss = new ServerSocket(0, 50, loopback);54Socket s1 = new Socket(loopback, ss.getLocalPort());) {55Server server = new Server(ss, Integer.parseInt(args[0]));56Future<Result> f1 = executor.submit(server);5758Client client = new Client(s1, Integer.parseInt(args[1]));59Future<Result> f2 = executor.submit(client);60long threadId = client.getID();6162sleep(200);63System.out.println("Sending SIGPIPE to client thread.");64if (NativeThread.signal(threadId, NativeThread.SIGPIPE) != 0) {65throw new RuntimeException("Failed to interrupt the thread.");66}6768Result r1 = f1.get();69if (r1.status == Result.FAIL) {70throw r1.exception;71}7273Result r2 = f2.get();74if (r2.status == Result.FAIL) {75throw r2.exception;76}77System.out.println("OK!");78} finally {79executor.shutdown();80}81}8283private static void sleep(long time) {84try {85Thread.sleep(time);86} catch (InterruptedException e) {87Thread.currentThread().interrupt();88}89}9091static class Client implements Callable<Result> {9293private volatile long threadId;94private final Socket client;95private final int timeout;9697public Client(Socket s, int timeout) {98client = s;99this.timeout = timeout;100}101102@Override103public Result call() {104threadId = NativeThread.getID();105byte[] arr = new byte[64];106try ( InputStream in = client.getInputStream();) {107client.setSoTimeout(timeout);108in.read(arr);109return new Result(Result.SUCCESS, null);110} catch (IOException ex) {111close();112return new Result(Result.FAIL, ex);113}114}115116long getID() {117while (threadId == 0) {118sleep(5);119}120return threadId;121}122123void close() {124if (!client.isClosed()) {125try {126client.close();127} catch (IOException ex) {128// ignore the exception.129}130}131}132}133134static class Server implements Callable<Result> {135136private final ServerSocket serverSocket;137private final int timeout;138139public Server(ServerSocket ss, int timeout) {140serverSocket = ss;141this.timeout = timeout;142}143144@Override145public Result call() {146try {147try ( Socket client = serverSocket.accept(); OutputStream outputStream = client.getOutputStream();) {148sleep(timeout);149outputStream.write("This is just a test string.".getBytes());150return new Result(Result.SUCCESS, null);151}152} catch (IOException e) {153close();154return new Result(Result.FAIL, e);155}156}157158public void close() {159if (!serverSocket.isClosed()) {160try {161serverSocket.close();162} catch (IOException ex) {163}164}165}166}167168static class Result {169170static final int SUCCESS = 0;171static final int FAIL = 1;172final int status;173final Exception exception;174175public Result(int status, Exception ex) {176this.status = status;177exception = ex;178}179}180}181182183