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.channels.*; 29e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.net.SocketAddress; 30e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.net.SocketOption; 31e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.net.StandardSocketOptions; 32e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.net.InetSocketAddress; 33e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.io.FileDescriptor; 34e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.io.IOException; 35e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.util.Set; 36e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.util.HashSet; 37e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.util.Collections; 38e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.util.concurrent.Future; 39e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.util.concurrent.locks.ReadWriteLock; 40e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.util.concurrent.locks.ReentrantReadWriteLock; 41e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport sun.net.NetHooks; 42e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 43e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera/** 44e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Base implementation of AsynchronousServerSocketChannel. 45e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 46e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 47e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraabstract class AsynchronousServerSocketChannelImpl 48e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera extends AsynchronousServerSocketChannel 49e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera implements Cancellable, Groupable 50e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera{ 51e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera protected final FileDescriptor fd; 52e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 53e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // the local address to which the channel's socket is bound 54e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera protected volatile InetSocketAddress localAddress = null; 55e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 56e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // need this lock to set local address 57e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private final Object stateLock = new Object(); 58e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 59e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // close support 60e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private ReadWriteLock closeLock = new ReentrantReadWriteLock(); 61e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private volatile boolean open = true; 62e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 63e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // set true when accept operation is cancelled 64e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private volatile boolean acceptKilled; 65e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 66e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // set true when exclusive binding is on and SO_REUSEADDR is emulated 67e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private boolean isReuseAddress; 68e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 69e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera AsynchronousServerSocketChannelImpl(AsynchronousChannelGroupImpl group) { 70e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera super(group.provider()); 71e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera this.fd = Net.serverSocket(true); 72e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 73e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 74e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 75e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final boolean isOpen() { 76e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return open; 77e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 78e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 79e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 80e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Marks beginning of access to file descriptor/handle 81e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 82e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final void begin() throws IOException { 83e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera closeLock.readLock().lock(); 84e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!isOpen()) 85e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new ClosedChannelException(); 86e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 87e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 88e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 89e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Marks end of access to file descriptor/handle 90e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 91e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final void end() { 92e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera closeLock.readLock().unlock(); 93e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 94e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 95e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 96e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Invoked to close file descriptor/handle. 97e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 98e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera abstract void implClose() throws IOException; 99e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 100e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 101e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final void close() throws IOException { 102e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // synchronize with any threads using file descriptor/handle 103e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera closeLock.writeLock().lock(); 104e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 105e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!open) 106e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return; // already closed 107e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera open = false; 108e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } finally { 109e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera closeLock.writeLock().unlock(); 110e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 111e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera implClose(); 112e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 113e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 114e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 115e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Invoked by accept to accept connection 116e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 117e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera abstract Future<AsynchronousSocketChannel> 118e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera implAccept(Object attachment, 119e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera CompletionHandler<AsynchronousSocketChannel,Object> handler); 120e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 121e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 122e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 123e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final Future<AsynchronousSocketChannel> accept() { 124e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return implAccept(null, null); 125e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 126e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 127e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 128e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @SuppressWarnings("unchecked") 129e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final <A> void accept(A attachment, 130e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera CompletionHandler<AsynchronousSocketChannel,? super A> handler) 131e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 132e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (handler == null) 133e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new NullPointerException("'handler' is null"); 134e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera implAccept(attachment, (CompletionHandler<AsynchronousSocketChannel,Object>)handler); 135e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 136e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 137e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final boolean isAcceptKilled() { 138e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return acceptKilled; 139e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 140e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 141e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 142e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final void onCancel(PendingFuture<?,?> task) { 143e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera acceptKilled = true; 144e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 145e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 146e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 147e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final AsynchronousServerSocketChannel bind(SocketAddress local, int backlog) 148e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throws IOException 149e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 150e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera InetSocketAddress isa = (local == null) ? new InetSocketAddress(0) : 151e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.checkAddress(local); 152e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera SecurityManager sm = System.getSecurityManager(); 153e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (sm != null) 154e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sm.checkListen(isa.getPort()); 155e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 156e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 157e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera begin(); 158e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera synchronized (stateLock) { 159e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (localAddress != null) 160e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new AlreadyBoundException(); 161e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort()); 162e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.bind(fd, isa.getAddress(), isa.getPort()); 163e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.listen(fd, backlog < 1 ? 50 : backlog); 164e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera localAddress = Net.localAddress(fd); 165e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 166e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } finally { 167e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera end(); 168e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 169e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return this; 170e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 171e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 172e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 173e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final SocketAddress getLocalAddress() throws IOException { 174e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!isOpen()) 175e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new ClosedChannelException(); 176e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return Net.getRevealedLocalAddress(localAddress); 177e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 178e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 179e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 180e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final <T> AsynchronousServerSocketChannel setOption(SocketOption<T> name, 181e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera T value) 182e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throws IOException 183e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 184e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (name == null) 185e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new NullPointerException(); 186e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!supportedOptions().contains(name)) 187e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new UnsupportedOperationException("'" + name + "' not supported"); 188e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 189e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 190e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera begin(); 191e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (name == StandardSocketOptions.SO_REUSEADDR && 192e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.useExclusiveBind()) 193e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 194e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // SO_REUSEADDR emulated when using exclusive bind 195e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera isReuseAddress = (Boolean)value; 196e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } else { 197e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.setSocketOption(fd, Net.UNSPEC, name, value); 198e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 199e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return this; 200e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } finally { 201e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera end(); 202e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 203e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 204e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 205e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 206e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @SuppressWarnings("unchecked") 207e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final <T> T getOption(SocketOption<T> name) throws IOException { 208e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (name == null) 209e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new NullPointerException(); 210e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!supportedOptions().contains(name)) 211e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new UnsupportedOperationException("'" + name + "' not supported"); 212e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 213e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 214e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera begin(); 215e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (name == StandardSocketOptions.SO_REUSEADDR && 216e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.useExclusiveBind()) 217e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 218e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // SO_REUSEADDR emulated when using exclusive bind 219e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return (T)Boolean.valueOf(isReuseAddress); 220e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 221e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return (T) Net.getSocketOption(fd, Net.UNSPEC, name); 222e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } finally { 223e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera end(); 224e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 225e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 226e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 227e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private static class DefaultOptionsHolder { 228e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera static final Set<SocketOption<?>> defaultOptions = defaultOptions(); 229e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 230e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private static Set<SocketOption<?>> defaultOptions() { 231e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(2); 232e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera set.add(StandardSocketOptions.SO_RCVBUF); 233e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera set.add(StandardSocketOptions.SO_REUSEADDR); 234e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return Collections.unmodifiableSet(set); 235e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 236e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 237e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 238e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 239e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final Set<SocketOption<?>> supportedOptions() { 240e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return DefaultOptionsHolder.defaultOptions; 241e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 242e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 243e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 244e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public final String toString() { 245e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera StringBuilder sb = new StringBuilder(); 246e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append(this.getClass().getName()); 247e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append('['); 248e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!isOpen()) 249e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append("closed"); 250e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera else { 251e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (localAddress == null) { 252e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append("unbound"); 253e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } else { 254e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append(Net.getRevealedLocalAddressAsString(localAddress)); 255e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 256e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 257e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sb.append(']'); 258e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return sb.toString(); 259e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 260e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera} 261