1e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera/* 2519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. 3e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * 5e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * This code is free software; you can redistribute it and/or modify it 6e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * under the terms of the GNU General Public License version 2 only, as 7e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * published by the Free Software Foundation. Oracle designates this 8e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * particular file as subject to the "Classpath" exception as provided 9e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * by Oracle in the LICENSE file that accompanied this code. 10e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * 11e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * This code is distributed in the hope that it will be useful, but WITHOUT 12e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * version 2 for more details (a copy is included in the LICENSE file that 15e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * accompanied this code). 16e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * 17e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * You should have received a copy of the GNU General Public License version 18e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * 2 along with this work; if not, write to the Free Software Foundation, 19e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * 21e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * or visit www.oracle.com if you need additional information or have any 23e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * questions. 24e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 25e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 26e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmerapackage sun.nio.ch; 27e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 28e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.nio.ByteBuffer; 29e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.nio.channels.*; 30e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.net.SocketOption; 31e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.net.StandardSocketOptions; 32e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.net.SocketAddress; 33e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.net.InetSocketAddress; 34e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.io.IOException; 35e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.io.FileDescriptor; 36e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.util.Set; 37e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.util.HashSet; 38e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.util.Collections; 39e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.util.concurrent.*; 40e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.util.concurrent.locks.*; 41e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport sun.net.NetHooks; 42e573e88e89daf5efb323719c54117c5a423eb245Yi Kongimport sun.net.ExtendedOptionsImpl; 43e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 44e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera/** 45e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Base implementation of AsynchronousSocketChannel 46e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 47e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 48e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraabstract class AsynchronousSocketChannelImpl 49e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera extends AsynchronousSocketChannel 50e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera implements Cancellable, Groupable 51e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera{ 52e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera protected final FileDescriptor fd; 53e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 54e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // protects state, localAddress, and remoteAddress 55e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera protected final Object stateLock = new Object(); 56e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 57e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera protected volatile InetSocketAddress localAddress = null; 58e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera protected volatile InetSocketAddress remoteAddress = null; 59e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 60e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // State, increases monotonically 61e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera static final int ST_UNINITIALIZED = -1; 62e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera static final int ST_UNCONNECTED = 0; 63e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera static final int ST_PENDING = 1; 64e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera static final int ST_CONNECTED = 2; 65e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera protected volatile int state = ST_UNINITIALIZED; 66e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 67e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // reading state 68e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private final Object readLock = new Object(); 69e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private boolean reading; 70e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private boolean readShutdown; 71e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private boolean readKilled; // further reading disallowed due to timeout 72e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 73e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // writing state 74e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private final Object writeLock = new Object(); 75e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private boolean writing; 76e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private boolean writeShutdown; 77e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private boolean writeKilled; // further writing disallowed due to timeout 78e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 79e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // close support 80e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private final ReadWriteLock closeLock = new ReentrantReadWriteLock(); 81e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private volatile boolean open = true; 82e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 83e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // set true when exclusive binding is on and SO_REUSEADDR is emulated 84e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private boolean isReuseAddress; 85e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 86e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera AsynchronousSocketChannelImpl(AsynchronousChannelGroupImpl group) 87e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throws IOException 88e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 89e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera super(group.provider()); 90e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera this.fd = Net.socket(true); 91e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera this.state = ST_UNCONNECTED; 92e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 93e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 94e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // Constructor for sockets obtained from AsynchronousServerSocketChannelImpl 95e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera AsynchronousSocketChannelImpl(AsynchronousChannelGroupImpl group, 96e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera FileDescriptor fd, 97e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera InetSocketAddress remote) 98e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throws IOException 99e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 100e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera super(group.provider()); 101e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera this.fd = fd; 102e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera this.state = ST_CONNECTED; 103e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera this.localAddress = Net.localAddress(fd); 104e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera this.remoteAddress = remote; 105e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 106e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 107e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 108e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final boolean isOpen() { 109e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return open; 110e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 111e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 112e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 113e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Marks beginning of access to file descriptor/handle 114e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 115e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final void begin() throws IOException { 116e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera closeLock.readLock().lock(); 117e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!isOpen()) 118e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new ClosedChannelException(); 119e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 120e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 121e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 122e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Marks end of access to file descriptor/handle 123e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 124e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final void end() { 125e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera closeLock.readLock().unlock(); 126e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 127e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 128e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 129e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Invoked to close socket and release other resources. 130e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 131e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera abstract void implClose() throws IOException; 132e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 133e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 134e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final void close() throws IOException { 135e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // synchronize with any threads initiating asynchronous operations 136e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera closeLock.writeLock().lock(); 137e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 138e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!open) 139e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return; // already closed 140e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera open = false; 141e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } finally { 142e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera closeLock.writeLock().unlock(); 143e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 144e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera implClose(); 145e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 146e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 147e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final void enableReading(boolean killed) { 148e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera synchronized (readLock) { 149e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera reading = false; 150e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (killed) 151e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera readKilled = true; 152e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 153e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 154e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 155e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final void enableReading() { 156e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera enableReading(false); 157e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 158e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 159e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final void enableWriting(boolean killed) { 160e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera synchronized (writeLock) { 161e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera writing = false; 162e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (killed) 163e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera writeKilled = true; 164e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 165e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 166e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 167e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final void enableWriting() { 168e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera enableWriting(false); 169e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 170e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 171e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final void killReading() { 172e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera synchronized (readLock) { 173e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera readKilled = true; 174e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 175e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 176e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 177e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final void killWriting() { 178e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera synchronized (writeLock) { 179e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera writeKilled = true; 180e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 181e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 182e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 183e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final void killConnect() { 184e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // when a connect is cancelled then the connection may have been 185e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // established so prevent reading or writing. 186e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera killReading(); 187e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera killWriting(); 188e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 189e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 190e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 191e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Invoked by connect to initiate the connect operation. 192e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 193e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera abstract <A> Future<Void> implConnect(SocketAddress remote, 194e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera A attachment, 195e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera CompletionHandler<Void,? super A> handler); 196e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 197e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 198e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final Future<Void> connect(SocketAddress remote) { 199e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return implConnect(remote, null, null); 200e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 201e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 202e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 203e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final <A> void connect(SocketAddress remote, 204e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera A attachment, 205e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera CompletionHandler<Void,? super A> handler) 206e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 207e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (handler == null) 208e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new NullPointerException("'handler' is null"); 209e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera implConnect(remote, attachment, handler); 210e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 211e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 212e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 213e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Invoked by read to initiate the I/O operation. 214e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 215e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera abstract <V extends Number,A> Future<V> implRead(boolean isScatteringRead, 216e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera ByteBuffer dst, 217e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera ByteBuffer[] dsts, 218e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera long timeout, 219e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera TimeUnit unit, 220e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera A attachment, 221e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera CompletionHandler<V,? super A> handler); 222e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 223e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @SuppressWarnings("unchecked") 224e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private <V extends Number,A> Future<V> read(boolean isScatteringRead, 225e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera ByteBuffer dst, 226e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera ByteBuffer[] dsts, 227e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera long timeout, 228e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera TimeUnit unit, 229e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera A att, 230e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera CompletionHandler<V,? super A> handler) 231e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 232e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!isOpen()) { 233e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Throwable e = new ClosedChannelException(); 234e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (handler == null) 235e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return CompletedFuture.withFailure(e); 236e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Invoker.invoke(this, handler, att, null, e); 237e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return null; 238e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 239e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 240e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (remoteAddress == null) 241e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new NotYetConnectedException(); 242e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 243e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera boolean hasSpaceToRead = isScatteringRead || dst.hasRemaining(); 244e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera boolean shutdown = false; 245e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 246e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // check and update state 247e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera synchronized (readLock) { 248e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (readKilled) 249e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalStateException("Reading not allowed due to timeout or cancellation"); 250e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (reading) 251e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new ReadPendingException(); 252e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (readShutdown) { 253e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera shutdown = true; 254e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } else { 255e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (hasSpaceToRead) { 256e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera reading = true; 257e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 258e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 259e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 260e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 261e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // immediately complete with -1 if shutdown for read 262e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // immediately complete with 0 if no space remaining 263e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (shutdown || !hasSpaceToRead) { 264e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Number result; 265e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (isScatteringRead) { 266e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera result = (shutdown) ? Long.valueOf(-1L) : Long.valueOf(0L); 267e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } else { 268e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera result = (shutdown) ? -1 : 0; 269e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 270e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (handler == null) 271e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return CompletedFuture.withResult((V)result); 272e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Invoker.invoke(this, handler, att, (V)result, null); 273e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return null; 274e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 275e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 276e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return implRead(isScatteringRead, dst, dsts, timeout, unit, att, handler); 277e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 278e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 279e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 280e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final Future<Integer> read(ByteBuffer dst) { 281e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (dst.isReadOnly()) 282e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalArgumentException("Read-only buffer"); 283e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return read(false, dst, null, 0L, TimeUnit.MILLISECONDS, null, null); 284e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 285e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 286e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 287e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final <A> void read(ByteBuffer dst, 288e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera long timeout, 289e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera TimeUnit unit, 290e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera A attachment, 291e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera CompletionHandler<Integer,? super A> handler) 292e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 293e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (handler == null) 294e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new NullPointerException("'handler' is null"); 295e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (dst.isReadOnly()) 296e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalArgumentException("Read-only buffer"); 297e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera read(false, dst, null, timeout, unit, attachment, handler); 298e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 299e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 300e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 301e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final <A> void read(ByteBuffer[] dsts, 302e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera int offset, 303e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera int length, 304e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera long timeout, 305e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera TimeUnit unit, 306e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera A attachment, 307e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera CompletionHandler<Long,? super A> handler) 308e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 309e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (handler == null) 310e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new NullPointerException("'handler' is null"); 311e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if ((offset < 0) || (length < 0) || (offset > dsts.length - length)) 312e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IndexOutOfBoundsException(); 313e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera ByteBuffer[] bufs = Util.subsequence(dsts, offset, length); 314e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera for (int i=0; i<bufs.length; i++) { 315e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (bufs[i].isReadOnly()) 316e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalArgumentException("Read-only buffer"); 317e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 318e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera read(true, null, bufs, timeout, unit, attachment, handler); 319e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 320e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 321e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 322e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Invoked by write to initiate the I/O operation. 323e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 324e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera abstract <V extends Number,A> Future<V> implWrite(boolean isGatheringWrite, 325e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera ByteBuffer src, 326e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera ByteBuffer[] srcs, 327e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera long timeout, 328e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera TimeUnit unit, 329e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera A attachment, 330e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera CompletionHandler<V,? super A> handler); 331e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 332e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @SuppressWarnings("unchecked") 333e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private <V extends Number,A> Future<V> write(boolean isGatheringWrite, 334e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera ByteBuffer src, 335e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera ByteBuffer[] srcs, 336e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera long timeout, 337e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera TimeUnit unit, 338e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera A att, 339e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera CompletionHandler<V,? super A> handler) 340e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 341e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera boolean hasDataToWrite = isGatheringWrite || src.hasRemaining(); 342e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 343e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera boolean closed = false; 344e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (isOpen()) { 345e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (remoteAddress == null) 346e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new NotYetConnectedException(); 347e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // check and update state 348e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera synchronized (writeLock) { 349e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (writeKilled) 350e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalStateException("Writing not allowed due to timeout or cancellation"); 351e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (writing) 352e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new WritePendingException(); 353e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (writeShutdown) { 354e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera closed = true; 355e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } else { 356e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (hasDataToWrite) 357e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera writing = true; 358e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 359e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 360e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } else { 361e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera closed = true; 362e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 363e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 364e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // channel is closed or shutdown for write 365e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (closed) { 366e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Throwable e = new ClosedChannelException(); 367e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (handler == null) 368e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return CompletedFuture.withFailure(e); 369e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Invoker.invoke(this, handler, att, null, e); 370e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return null; 371e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 372e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 373e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // nothing to write so complete immediately 374e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!hasDataToWrite) { 375e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Number result = (isGatheringWrite) ? (Number)0L : (Number)0; 376e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (handler == null) 377e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return CompletedFuture.withResult((V)result); 378e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Invoker.invoke(this, handler, att, (V)result, null); 379e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return null; 380e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 381e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 382e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return implWrite(isGatheringWrite, src, srcs, timeout, unit, att, handler); 383e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 384e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 385e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 386e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final Future<Integer> write(ByteBuffer src) { 387e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return write(false, src, null, 0L, TimeUnit.MILLISECONDS, null, null); 388e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 389e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 390e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 391e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final <A> void write(ByteBuffer src, 392e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera long timeout, 393e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera TimeUnit unit, 394e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera A attachment, 395e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera CompletionHandler<Integer,? super A> handler) 396e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 397e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (handler == null) 398e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new NullPointerException("'handler' is null"); 399e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera write(false, src, null, timeout, unit, attachment, handler); 400e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 401e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 402e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 403e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final <A> void write(ByteBuffer[] srcs, 404e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera int offset, 405e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera int length, 406e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera long timeout, 407e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera TimeUnit unit, 408e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera A attachment, 409e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera CompletionHandler<Long,? super A> handler) 410e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 411e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (handler == null) 412e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new NullPointerException("'handler' is null"); 413e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if ((offset < 0) || (length < 0) || (offset > srcs.length - length)) 414e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IndexOutOfBoundsException(); 415e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera srcs = Util.subsequence(srcs, offset, length); 416e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera write(true, null, srcs, timeout, unit, attachment, handler); 417e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 418e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 419e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 420e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final AsynchronousSocketChannel bind(SocketAddress local) 421e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throws IOException 422e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 423e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 424e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera begin(); 425e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera synchronized (stateLock) { 426e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (state == ST_PENDING) 427e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new ConnectionPendingException(); 428e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (localAddress != null) 429e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new AlreadyBoundException(); 430e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera InetSocketAddress isa = (local == null) ? 431e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera new InetSocketAddress(0) : Net.checkAddress(local); 432519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera SecurityManager sm = System.getSecurityManager(); 433519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (sm != null) { 434519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera sm.checkListen(isa.getPort()); 435519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 436e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort()); 437e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.bind(fd, isa.getAddress(), isa.getPort()); 438e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera localAddress = Net.localAddress(fd); 439e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 440e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } finally { 441e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera end(); 442e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 443e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return this; 444e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 445e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 446e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 447e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final SocketAddress getLocalAddress() throws IOException { 448e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!isOpen()) 449e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new ClosedChannelException(); 450e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return Net.getRevealedLocalAddress(localAddress); 451e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 452e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 453e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 454e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final <T> AsynchronousSocketChannel setOption(SocketOption<T> name, T value) 455e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throws IOException 456e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 457e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (name == null) 458e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new NullPointerException(); 459e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!supportedOptions().contains(name)) 460e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new UnsupportedOperationException("'" + name + "' not supported"); 461e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 462e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 463e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera begin(); 464e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (writeShutdown) 465e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IOException("Connection has been shutdown for writing"); 466e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (name == StandardSocketOptions.SO_REUSEADDR && 467e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.useExclusiveBind()) 468e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 469e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // SO_REUSEADDR emulated when using exclusive bind 470e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera isReuseAddress = (Boolean)value; 471e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } else { 472e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.setSocketOption(fd, Net.UNSPEC, name, value); 473e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 474e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return this; 475e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } finally { 476e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera end(); 477e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 478e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 479e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 480e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 481e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @SuppressWarnings("unchecked") 482e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final <T> T getOption(SocketOption<T> name) throws IOException { 483e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (name == null) 484e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new NullPointerException(); 485e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!supportedOptions().contains(name)) 486e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new UnsupportedOperationException("'" + name + "' not supported"); 487e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 488e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 489e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera begin(); 490e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (name == StandardSocketOptions.SO_REUSEADDR && 491e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.useExclusiveBind()) 492e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 493e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // SO_REUSEADDR emulated when using exclusive bind 494e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return (T)Boolean.valueOf(isReuseAddress); 495e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 496e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return (T) Net.getSocketOption(fd, Net.UNSPEC, name); 497e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } finally { 498e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera end(); 499e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 500e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 501e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 502e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private static class DefaultOptionsHolder { 503e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera static final Set<SocketOption<?>> defaultOptions = defaultOptions(); 504e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 505e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private static Set<SocketOption<?>> defaultOptions() { 506e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(5); 507e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera set.add(StandardSocketOptions.SO_SNDBUF); 508e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera set.add(StandardSocketOptions.SO_RCVBUF); 509e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera set.add(StandardSocketOptions.SO_KEEPALIVE); 510e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera set.add(StandardSocketOptions.SO_REUSEADDR); 511e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera set.add(StandardSocketOptions.TCP_NODELAY); 512e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (ExtendedOptionsImpl.flowSupported()) { 513e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA); 514e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 515e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return Collections.unmodifiableSet(set); 516e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 517e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 518e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 519e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 520e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final Set<SocketOption<?>> supportedOptions() { 521e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return DefaultOptionsHolder.defaultOptions; 522e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 523e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 524e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 525e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final SocketAddress getRemoteAddress() throws IOException { 526e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!isOpen()) 527e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new ClosedChannelException(); 528e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return remoteAddress; 529e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 530e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 531e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 532e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final AsynchronousSocketChannel shutdownInput() throws IOException { 533e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 534e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera begin(); 535e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (remoteAddress == null) 536e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new NotYetConnectedException(); 537e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera synchronized (readLock) { 538e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!readShutdown) { 539e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.shutdown(fd, Net.SHUT_RD); 540e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera readShutdown = true; 541e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 542e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 543e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } finally { 544e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera end(); 545e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 546e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return this; 547e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 548e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 549e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 550e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final AsynchronousSocketChannel shutdownOutput() throws IOException { 551e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 552e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera begin(); 553e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (remoteAddress == null) 554e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new NotYetConnectedException(); 555e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera synchronized (writeLock) { 556e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!writeShutdown) { 557e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.shutdown(fd, Net.SHUT_WR); 558e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera writeShutdown = true; 559e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 560e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 561e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } finally { 562e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera end(); 563e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 564e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return this; 565e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 566e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 567e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 568e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final String toString() { 569e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera StringBuilder sb = new StringBuilder(); 570e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append(this.getClass().getName()); 571e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append('['); 572e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera synchronized (stateLock) { 573e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!isOpen()) { 574e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append("closed"); 575e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } else { 576e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera switch (state) { 577e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera case ST_UNCONNECTED: 578e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append("unconnected"); 579e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera break; 580e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera case ST_PENDING: 581e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append("connection-pending"); 582e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera break; 583e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera case ST_CONNECTED: 584e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append("connected"); 585e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (readShutdown) 586e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append(" ishut"); 587e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (writeShutdown) 588e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append(" oshut"); 589e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera break; 590e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 591e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (localAddress != null) { 592e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append(" local="); 593e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append( 594e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.getRevealedLocalAddressAsString(localAddress)); 595e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 596e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (remoteAddress != null) { 597e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append(" remote="); 598e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append(remoteAddress.toString()); 599e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 600e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 601e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 602e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append(']'); 603e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return sb.toString(); 604e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 605e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera} 606