151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project 3519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.nio.ch; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.FileDescriptor; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException; 315ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.InetAddress; 325ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.InetSocketAddress; 335ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.ProtocolFamily; 345ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.Socket; 355ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.SocketAddress; 365ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.SocketOption; 375ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.StandardProtocolFamily; 385ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.StandardSocketOptions; 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.ByteBuffer; 405ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.AlreadyBoundException; 415ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.AlreadyConnectedException; 425ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.AsynchronousCloseException; 435ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.ClosedChannelException; 445ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.ConnectionPendingException; 455ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.NoConnectionPendingException; 465ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.NotYetConnectedException; 475ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.SelectionKey; 485ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.SocketChannel; 495ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.spi.SelectorProvider; 505ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.util.Collections; 515ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.util.HashSet; 525ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.util.Set; 531d568d5e72820f7e487a49e3c57dee4f1e7f14bcNarayan Kamath 54e31b37859051d3902e06e4ba384995df7188917fHans Boehmimport dalvik.annotation.optimization.ReachabilitySensitive; 551d568d5e72820f7e487a49e3c57dee4f1e7f14bcNarayan Kamathimport dalvik.system.BlockGuard; 565ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport dalvik.system.CloseGuard; 57e573e88e89daf5efb323719c54117c5a423eb245Yi Kongimport sun.net.ExtendedOptionsImpl; 585ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport sun.net.NetHooks; 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 60519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * An implementation of SocketChannels 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass SocketChannelImpl 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski extends SocketChannel 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski implements SelChImpl 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Used to make native read and write calls 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static NativeDispatcher nd; 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Our file descriptor object 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final FileDescriptor fd; 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // fd value needed for dev/poll. This value will remain valid 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // even after the value in the file descriptor object has been set to -1 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final int fdVal; 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // IDs of native threads doing reads and writes, for signalling 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private volatile long readerThread = 0; 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private volatile long writerThread = 0; 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Lock held by current reading or connecting thread 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Object readLock = new Object(); 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Lock held by current writing or connecting thread 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Object writeLock = new Object(); 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Lock held by any thread that modifies the state fields declared below 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // DO NOT invoke a blocking I/O operation while holding this lock! 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Object stateLock = new Object(); 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- The following fields are protected by stateLock 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // set true when exclusive binding is on and SO_REUSEADDR is emulated 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean isReuseAddress; 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // State, increases monotonically 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int ST_UNINITIALIZED = -1; 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int ST_UNCONNECTED = 0; 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int ST_PENDING = 1; 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int ST_CONNECTED = 2; 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int ST_KILLPENDING = 3; 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int ST_KILLED = 4; 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int state = ST_UNINITIALIZED; 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Binding 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private InetSocketAddress localAddress; 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private InetSocketAddress remoteAddress; 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Input/Output open 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean isInputOpen = true; 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean isOutputOpen = true; 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean readyToConnect = false; 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Socket adaptor, created on demand 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Socket socket; 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- End of fields protected by stateLock 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 122dd2c67a47dc742e19c6710ddd6e1b85f95dd1d1fNeil Fuller // Android-added: CloseGuard support. 123e31b37859051d3902e06e4ba384995df7188917fHans Boehm @ReachabilitySensitive 1245ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera private final CloseGuard guard = CloseGuard.get(); 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Constructor for normal connecting sockets 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SocketChannelImpl(SelectorProvider sp) throws IOException { 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(sp); 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fd = Net.socket(true); 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fdVal = IOUtil.fdVal(fd); 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.state = ST_UNCONNECTED; 1335ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera 134dd2c67a47dc742e19c6710ddd6e1b85f95dd1d1fNeil Fuller // Android-added: CloseGuard support. 1355ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera // Net#socket will set |fd| if it succeeds. 1365ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera if (fd != null && fd.valid()) { 1375ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera guard.open("close"); 1385ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera } 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SocketChannelImpl(SelectorProvider sp, 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FileDescriptor fd, 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean bound) 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(sp); 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fd = fd; 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fdVal = IOUtil.fdVal(fd); 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.state = ST_UNCONNECTED; 1505ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera 151dd2c67a47dc742e19c6710ddd6e1b85f95dd1d1fNeil Fuller // Android-added: CloseGuard support. 1525ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera if (fd != null && fd.valid()) { 1535ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera guard.open("close"); 1545ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera } 1555ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bound) 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.localAddress = Net.localAddress(fd); 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Constructor for sockets obtained from server sockets 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SocketChannelImpl(SelectorProvider sp, 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FileDescriptor fd, InetSocketAddress remote) 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(sp); 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fd = fd; 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fdVal = IOUtil.fdVal(fd); 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.state = ST_CONNECTED; 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.localAddress = Net.localAddress(fd); 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.remoteAddress = remote; 172dd2c67a47dc742e19c6710ddd6e1b85f95dd1d1fNeil Fuller // Android-added: CloseGuard support. 1735ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera if (fd != null && fd.valid()) { 1745ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera guard.open("close"); 1755ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera } 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Socket socket() { 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (socket == null) 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski socket = SocketAdaptor.create(this); 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return socket; 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SocketAddress getLocalAddress() throws IOException { 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Net.getRevealedLocalAddress(localAddress); 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SocketAddress getRemoteAddress() throws IOException { 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return remoteAddress; 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public <T> SocketChannel setOption(SocketOption<T> name, T value) 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == null) 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!supportedOptions().contains(name)) 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UnsupportedOperationException("'" + name + "' not supported"); 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == StandardSocketOptions.IP_TOS) { 218519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera ProtocolFamily family = Net.isIPv6Available() ? 219519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; 220519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera Net.setSocketOption(fd, family, name, value); 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 222519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 223519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 224519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (name == StandardSocketOptions.SO_REUSEADDR && Net.useExclusiveBind()) { 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // SO_REUSEADDR emulated when using exclusive bind 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isReuseAddress = (Boolean)value; 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // no options that require special handling 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.setSocketOption(fd, Net.UNSPEC, name, value); 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @SuppressWarnings("unchecked") 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public <T> T getOption(SocketOption<T> name) 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == null) 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!supportedOptions().contains(name)) 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UnsupportedOperationException("'" + name + "' not supported"); 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == StandardSocketOptions.SO_REUSEADDR && 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.useExclusiveBind()) 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // SO_REUSEADDR emulated when using exclusive bind 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (T)Boolean.valueOf(isReuseAddress); 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // special handling for IP_TOS: always return 0 when IPv6 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == StandardSocketOptions.IP_TOS) { 259519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera ProtocolFamily family = Net.isIPv6Available() ? 260519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; 261519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera return (T) Net.getSocketOption(fd, family, name); 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // no options that require special handling 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (T) Net.getSocketOption(fd, Net.UNSPEC, name); 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static class DefaultOptionsHolder { 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static final Set<SocketOption<?>> defaultOptions = defaultOptions(); 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static Set<SocketOption<?>> defaultOptions() { 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(8); 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.SO_SNDBUF); 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.SO_RCVBUF); 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.SO_KEEPALIVE); 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.SO_REUSEADDR); 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.SO_LINGER); 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.TCP_NODELAY); 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // additional options required by socket adaptor 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.IP_TOS); 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(ExtendedSocketOption.SO_OOBINLINE); 283e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (ExtendedOptionsImpl.flowSupported()) { 284e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA); 285e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Collections.unmodifiableSet(set); 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final Set<SocketOption<?>> supportedOptions() { 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return DefaultOptionsHolder.defaultOptions; 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean ensureReadOpen() throws ClosedChannelException { 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isConnected()) 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NotYetConnectedException(); 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isInputOpen) 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void ensureWriteOpen() throws ClosedChannelException { 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOutputOpen) 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isConnected()) 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NotYetConnectedException(); 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void readerCleanup() throws IOException { 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readerThread = 0; 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state == ST_KILLPENDING) 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski kill(); 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void writerCleanup() throws IOException { 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writerThread = 0; 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state == ST_KILLPENDING) 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski kill(); 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int read(ByteBuffer buf) throws IOException { 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (buf == null) 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (readLock) { 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!ensureReadOpen()) 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 0; 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Set up the interruption machinery; see 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // AbstractInterruptibleChannel for details 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) { 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Either the current thread is already interrupted, so 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // begin() closed the channel, or another thread closed the 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // channel since we checked it a few bytecodes ago. In 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // either case the value returned here is irrelevant since 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the invocation of end() in the finally block will throw 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // an appropriate exception. 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Save this thread so that it can be signalled on those 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // platforms that require it 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readerThread = NativeThread.current(); 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Between the previous test of isOpen() and the return of the 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // IOUtil.read invocation below, this channel might be closed 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // or this thread might be interrupted. We rely upon the 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // implicit synchronization point in the kernel read() call to 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // make sure that the right thing happens. In either case the 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // implCloseSelectableChannel method is ultimately invoked in 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // some other thread, so there are three possibilities: 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // - implCloseSelectableChannel() invokes nd.preClose() 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // before this thread invokes read(), in which case the 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // read returns immediately with either EOF or an error, 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the latter of which will cause an IOException to be 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // thrown. 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // - implCloseSelectableChannel() invokes nd.preClose() after 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // this thread is blocked in read(). On some operating 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // systems (e.g., Solaris and Windows) this causes the read 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // to return immediately with either EOF or an error 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // indication. 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // - implCloseSelectableChannel() invokes nd.preClose() after 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // this thread is blocked in read() but the operating 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // system (e.g., Linux) doesn't support preemptive close, 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // so implCloseSelectableChannel() proceeds to signal this 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // thread, thereby causing the read to return immediately 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // with IOStatus.INTERRUPTED. 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // In all three cases the invocation of end() in the finally 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // clause will notice that the channel has been closed and 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // throw an appropriate exception (AsynchronousCloseException 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // or ClosedByInterruptException) if necessary. 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // *There is A fourth possibility. implCloseSelectableChannel() 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // invokes nd.preClose(), signals reader/writer thred and quickly 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // moves on to nd.close() in kill(), which does a real close. 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Then a third thread accepts a new connection, opens file or 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // whatever that causes the released "fd" to be recycled. All 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // above happens just between our last isOpen() check and the 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // next kernel read reached, with the recycled "fd". The solution 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // is to postpone the real kill() if there is a reader or/and 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // writer thread(s) over there "waiting", leave the cleanup/kill 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // to the reader or writer thread. (the preClose() still happens 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // so the connection gets cut off as usual). 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // For socket channels there is the additional wrinkle that 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // asynchronous shutdown works much like asynchronous close, 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // except that the channel is shutdown rather than completely 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // closed. This is analogous to the first two cases above, 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // except that the shutdown operation plays the role of 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // nd.preClose(). 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (;;) { 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = IOUtil.read(fd, buf, -1, nd); 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((n == IOStatus.INTERRUPTED) && isOpen()) { 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The system call was interrupted but the channel 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // is still open, so retry 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readerCleanup(); // Clear reader thread 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The end method, which is defined in our superclass 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // AbstractInterruptibleChannel, resets the interruption 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // machinery. If its argument is true then it returns 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // normally; otherwise it checks the interrupt and open state 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // of this channel and throws an appropriate exception if 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // necessary. 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // So, if we actually managed to do any I/O in the above try 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // block then we pass true to the end method. We also pass 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // true if the channel was in non-blocking mode when the I/O 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // operation was initiated but no data could be transferred; 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // this prevents spurious exceptions from being thrown in the 44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // rare event that a channel is closed or a thread is 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // interrupted at the exact moment that a non-blocking I/O 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // request is made. 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(n > 0 || (n == IOStatus.UNAVAILABLE)); 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Extra case for socket channels: Asynchronous shutdown 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((n <= 0) && (!isInputOpen)) 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.EOF; 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long read(ByteBuffer[] dsts, int offset, int length) 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((offset < 0) || (length < 0) || (offset > dsts.length - length)) 46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IndexOutOfBoundsException(); 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (readLock) { 46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!ensureReadOpen()) 47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long n = 0; 47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readerThread = NativeThread.current(); 47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (;;) { 48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = IOUtil.read(fd, dsts, offset, length, nd); 48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((n == IOStatus.INTERRUPTED) && isOpen()) 48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readerCleanup(); 48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(n > 0 || (n == IOStatus.UNAVAILABLE)); 48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((n <= 0) && (!isInputOpen)) 49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.EOF; 49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int write(ByteBuffer buf) throws IOException { 49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (buf == null) 50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (writeLock) { 50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureWriteOpen(); 50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 0; 50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writerThread = NativeThread.current(); 51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (;;) { 51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = IOUtil.write(fd, buf, -1, nd); 51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((n == IOStatus.INTERRUPTED) && isOpen()) 51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writerCleanup(); 51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(n > 0 || (n == IOStatus.UNAVAILABLE)); 52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((n <= 0) && (!isOutputOpen)) 52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new AsynchronousCloseException(); 52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long write(ByteBuffer[] srcs, int offset, int length) 53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((offset < 0) || (length < 0) || (offset > srcs.length - length)) 53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IndexOutOfBoundsException(); 53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (writeLock) { 53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureWriteOpen(); 53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long n = 0; 53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writerThread = NativeThread.current(); 54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (;;) { 54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = IOUtil.write(fd, srcs, offset, length, nd); 54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((n == IOStatus.INTERRUPTED) && isOpen()) 54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writerCleanup(); 55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end((n > 0) || (n == IOStatus.UNAVAILABLE)); 55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((n <= 0) && (!isOutputOpen)) 55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new AsynchronousCloseException(); 55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // package-private 56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int sendOutOfBandData(byte b) throws IOException { 56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (writeLock) { 56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureWriteOpen(); 56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 0; 56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writerThread = NativeThread.current(); 57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (;;) { 57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = sendOutOfBandData(fd, b); 57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((n == IOStatus.INTERRUPTED) && isOpen()) 57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writerCleanup(); 58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end((n > 0) || (n == IOStatus.UNAVAILABLE)); 58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((n <= 0) && (!isOutputOpen)) 58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new AsynchronousCloseException(); 58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void implConfigureBlocking(boolean block) throws IOException { 59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski IOUtil.configureBlocking(fd, block); 59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public InetSocketAddress localAddress() { 59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return localAddress; 59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SocketAddress remoteAddress() { 60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return remoteAddress; 60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SocketChannel bind(SocketAddress local) throws IOException { 61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (readLock) { 61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (writeLock) { 61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state == ST_PENDING) 61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ConnectionPendingException(); 61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (localAddress != null) 61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new AlreadyBoundException(); 61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress isa = (local == null) ? 62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new InetSocketAddress(0) : Net.checkAddress(local); 621519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera SecurityManager sm = System.getSecurityManager(); 622519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (sm != null) { 623519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera sm.checkListen(isa.getPort()); 624519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort()); 62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.bind(fd, isa.getAddress(), isa.getPort()); 62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski localAddress = Net.localAddress(fd); 62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isConnected() { 63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (state == ST_CONNECTED); 63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isConnectionPending() { 64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (state == ST_PENDING); 64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void ensureOpenAndUnconnected() throws IOException { // package-private 64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state == ST_CONNECTED) 65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new AlreadyConnectedException(); 65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state == ST_PENDING) 65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ConnectionPendingException(); 65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean connect(SocketAddress sa) throws IOException { 65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int localPort = 0; 65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (readLock) { 66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (writeLock) { 66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpenAndUnconnected(); 66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress isa = Net.checkAddress(sa); 66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager sm = System.getSecurityManager(); 66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sm != null) 66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sm.checkConnect(isa.getAddress().getHostAddress(), 66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isa.getPort()); 66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (blockingLock()) { 66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 0; 67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) { 67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // notify hook only if unbound 67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (localAddress == null) { 67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski NetHooks.beforeTcpConnect(fd, 68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isa.getAddress(), 68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isa.getPort()); 68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readerThread = NativeThread.current(); 68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (;;) { 68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetAddress ia = isa.getAddress(); 68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ia.isAnyLocalAddress()) 68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ia = InetAddress.getLocalHost(); 68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = Net.connect(fd, 69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ia, 69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isa.getPort()); 69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ( (n == IOStatus.INTERRUPTED) 69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski && isOpen()) 69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readerCleanup(); 70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end((n > 0) || (n == IOStatus.UNAVAILABLE)); 70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException x) { 70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If an exception was thrown, close the channel after 70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // invoking end() so as to avoid bogus 70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // AsynchronousCloseExceptions 70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski close(); 70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw x; 70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski remoteAddress = isa; 71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n > 0) { 71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Connection succeeded; disallow further 71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // invocation 71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski state = ST_CONNECTED; 71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isOpen()) 71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski localAddress = Net.localAddress(fd); 71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If nonblocking and no exception then connection 72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // pending; disallow another invocation 7232e1995a729cb8d836159444d61427d4d0ef0b45fNarayan Kamath if (!isBlocking()) { 72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski state = ST_PENDING; 7252e1995a729cb8d836159444d61427d4d0ef0b45fNarayan Kamath if (isOpen()) { 7262e1995a729cb8d836159444d61427d4d0ef0b45fNarayan Kamath localAddress = Net.localAddress(fd); 7272e1995a729cb8d836159444d61427d4d0ef0b45fNarayan Kamath } 7282e1995a729cb8d836159444d61427d4d0ef0b45fNarayan Kamath } 72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean finishConnect() throws IOException { 73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (readLock) { 73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (writeLock) { 73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 74051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state == ST_CONNECTED) 74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state != ST_PENDING) 74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NoConnectionPendingException(); 74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 0; 74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (blockingLock()) { 75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) { 75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readerThread = NativeThread.current(); 75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 7581d568d5e72820f7e487a49e3c57dee4f1e7f14bcNarayan Kamath 7591d568d5e72820f7e487a49e3c57dee4f1e7f14bcNarayan Kamath BlockGuard.getThreadPolicy().onNetwork(); 76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isBlocking()) { 76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (;;) { 76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = checkConnect(fd, false, 76351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readyToConnect); 76451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ( (n == IOStatus.INTERRUPTED) 76551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski && isOpen()) 76651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (;;) { 77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = checkConnect(fd, true, 77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readyToConnect); 77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n == 0) { 77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Loop in case of 77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // spurious notifications 77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ( (n == IOStatus.INTERRUPTED) 77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski && isOpen()) 78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readerThread = 0; 78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state == ST_KILLPENDING) { 78951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski kill(); 79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // poll()/getsockopt() does not report 79151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // error (throws exception, with n = 0) 79251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // on Linux platform after dup2 and 79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // signal-wakeup. Force n to 0 so the 79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // end() can throw appropriate exception 79551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = 0; 79651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 79751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 79851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end((n > 0) || (n == IOStatus.UNAVAILABLE)); 79951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 80051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException x) { 80251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If an exception was thrown, close the channel after 80351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // invoking end() so as to avoid bogus 80451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // AsynchronousCloseExceptions 80551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski close(); 80651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw x; 80751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n > 0) { 80951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 81051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski state = ST_CONNECTED; 81151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isOpen()) 81251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski localAddress = Net.localAddress(fd); 81351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 81551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 81751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SocketChannel shutdownInput() throws IOException { 82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isConnected()) 82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NotYetConnectedException(); 82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isInputOpen) { 82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.shutdown(fd, Net.SHUT_RD); 83051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (readerThread != 0) 83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski NativeThread.signal(readerThread); 83251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isInputOpen = false; 83351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 83551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 83651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 83751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 83851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 83951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SocketChannel shutdownOutput() throws IOException { 84051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 84151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 84251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 84351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isConnected()) 84451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NotYetConnectedException(); 84551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isOutputOpen) { 84651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.shutdown(fd, Net.SHUT_WR); 84751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (writerThread != 0) 84851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski NativeThread.signal(writerThread); 84951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isOutputOpen = false; 85051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 85151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 85251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 85351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 85451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 85551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isInputOpen() { 85651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 85751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return isInputOpen; 85851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 85951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 86051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 86151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isOutputOpen() { 86251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 86351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return isOutputOpen; 86451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 86551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 86651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 86751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // AbstractInterruptibleChannel synchronizes invocations of this method 86851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // using AbstractInterruptibleChannel.closeLock, and also ensures that this 86951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // method is only ever invoked once. Before we get to this method, isOpen 87051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // (which is volatile) will have been set to false. 87151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 87251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void implCloseSelectableChannel() throws IOException { 87351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 87451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isInputOpen = false; 87551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isOutputOpen = false; 87651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 87751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Close the underlying file descriptor and dup it to a known fd 87851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // that's already closed. This prevents other operations on this 87951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // channel from using the old fd, which might be recycled in the 88051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // meantime and allocated to an entirely different channel. 88151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 8825ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera if (state != ST_KILLED) { 883dd2c67a47dc742e19c6710ddd6e1b85f95dd1d1fNeil Fuller // Android-added: CloseGuard support. 8845ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera guard.close(); 88551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nd.preClose(fd); 8865ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera } 88751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 88851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Signal native threads, if needed. If a target thread is not 88951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // currently blocked in an I/O operation then no harm is done since 89051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the signal handler doesn't actually do anything. 89151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 89251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (readerThread != 0) 89351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski NativeThread.signal(readerThread); 89451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 89551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (writerThread != 0) 89651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski NativeThread.signal(writerThread); 89751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 89851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If this channel is not registered then it's safe to close the fd 89951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // immediately since we know at this point that no thread is 90051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // blocked in an I/O operation upon the channel and, since the 90151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // channel is marked closed, no thread will start another such 90251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // operation. If this channel is registered then we don't close 90351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the fd since it might be in use by a selector. In that case 90451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // closing this channel caused its keys to be cancelled, so the 90551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // last selector to deregister a key for this channel will invoke 90651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // kill() to close the fd. 90751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 90851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isRegistered()) 90951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski kill(); 91051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 91151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 91251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 91351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void kill() throws IOException { 91451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 91551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state == ST_KILLED) 91651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 91751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state == ST_UNINITIALIZED) { 91851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski state = ST_KILLED; 91951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 92051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 92151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert !isOpen() && !isRegistered(); 92251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 92351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Postpone the kill if there is a waiting reader 92451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // or writer thread. See the comments in read() for 92551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // more detailed explanation. 92651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (readerThread == 0 && writerThread == 0) { 92751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nd.close(fd); 92851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski state = ST_KILLED; 92951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 93051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski state = ST_KILLPENDING; 93151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 93251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 93351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 93451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9355ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera protected void finalize() throws IOException { 9365ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera if (guard != null) { 9375ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera guard.warnIfOpen(); 9385ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera } 9395ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera close(); 9405ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera } 9415ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera 94251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 94351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Translates native poll revent ops into a ready operation ops 94451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 94551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean translateReadyOps(int ops, int initialOps, 94651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SelectionKeyImpl sk) { 94751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int intOps = sk.nioInterestOps(); // Do this just once, it synchronizes 94851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int oldOps = sk.nioReadyOps(); 94951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int newOps = initialOps; 95051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 951519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if ((ops & Net.POLLNVAL) != 0) { 95251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // This should only happen if this channel is pre-closed while a 95351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // selection operation is in progress 95451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ## Throw an error if this channel has not been pre-closed 95551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 95651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 95751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 958519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) { 95951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newOps = intOps; 96051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sk.nioReadyOps(newOps); 96151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // No need to poll again in checkConnect, 96251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the error will be detected there 96351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readyToConnect = true; 96451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (newOps & ~oldOps) != 0; 96551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 96651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 967519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (((ops & Net.POLLIN) != 0) && 96851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((intOps & SelectionKey.OP_READ) != 0) && 96951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (state == ST_CONNECTED)) 97051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newOps |= SelectionKey.OP_READ; 97151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 972519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (((ops & Net.POLLCONN) != 0) && 97351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((intOps & SelectionKey.OP_CONNECT) != 0) && 97451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((state == ST_UNCONNECTED) || (state == ST_PENDING))) { 97551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newOps |= SelectionKey.OP_CONNECT; 97651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readyToConnect = true; 97751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 97851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 979519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (((ops & Net.POLLOUT) != 0) && 98051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((intOps & SelectionKey.OP_WRITE) != 0) && 98151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (state == ST_CONNECTED)) 98251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newOps |= SelectionKey.OP_WRITE; 98351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 98451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sk.nioReadyOps(newOps); 98551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (newOps & ~oldOps) != 0; 98651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 98751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 98851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) { 98951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return translateReadyOps(ops, sk.nioReadyOps(), sk); 99051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 99151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 99251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) { 99351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return translateReadyOps(ops, 0, sk); 99451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 99551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 996519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera // package-private 997519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera int poll(int events, long timeout) throws IOException { 998519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera assert Thread.holdsLock(blockingLock()) && !isBlocking(); 999519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 1000519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera synchronized (readLock) { 1001519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera int n = 0; 1002519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera try { 1003519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera begin(); 1004519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera synchronized (stateLock) { 1005519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (!isOpen()) 1006519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera return 0; 1007519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera readerThread = NativeThread.current(); 1008519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 1009519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera n = Net.poll(fd, events, timeout); 1010519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } finally { 1011519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera readerCleanup(); 1012519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera end(n > 0); 1013519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 1014519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera return n; 1015519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 1016519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 1017519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 101851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 101951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Translates an interest operation set into a native poll event set 102051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 102151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) { 102251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int newOps = 0; 102351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((ops & SelectionKey.OP_READ) != 0) 1024519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera newOps |= Net.POLLIN; 102551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((ops & SelectionKey.OP_WRITE) != 0) 1026519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera newOps |= Net.POLLOUT; 102751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((ops & SelectionKey.OP_CONNECT) != 0) 1028519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera newOps |= Net.POLLCONN; 102951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sk.selector.putEventOps(sk, newOps); 103051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 103151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 103251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public FileDescriptor getFD() { 103351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return fd; 103451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 103551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 103651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getFDVal() { 103751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return fdVal; 103851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 103951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 104051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 104151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String toString() { 104251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski StringBuffer sb = new StringBuffer(); 104351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append(this.getClass().getSuperclass().getName()); 104451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append('['); 104551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 104651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append("closed"); 104751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else { 104851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 104951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (state) { 105051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case ST_UNCONNECTED: 105151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append("unconnected"); 105251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 105351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case ST_PENDING: 105451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append("connection-pending"); 105551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 105651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case ST_CONNECTED: 105751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append("connected"); 105851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isInputOpen) 105951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append(" ishut"); 106051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOutputOpen) 106151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append(" oshut"); 106251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 106351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 106451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress addr = localAddress(); 106551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (addr != null) { 106651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append(" local="); 106751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append(Net.getRevealedLocalAddressAsString(addr)); 106851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 106951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (remoteAddress() != null) { 107051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append(" remote="); 107151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append(remoteAddress().toString()); 107251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append(']'); 107651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return sb.toString(); 107751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 107951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 108051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- Native methods -- 108151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 108251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static native int checkConnect(FileDescriptor fd, 108351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean block, boolean ready) 108451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException; 108551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 108651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static native int sendOutOfBandData(FileDescriptor fd, byte data) 108751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException; 108851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 108951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static { 109051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nd = new SocketDispatcher(); 109151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 109251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 109351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 1094