151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.nio.ch; 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.FileDescriptor; 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.net.*; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.channels.*; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.channels.spi.*; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.*; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.net.NetHooks; 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * An implementation of ServerSocketChannels 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass ServerSocketChannelImpl 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski extends ServerSocketChannel 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski implements SelChImpl 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Used to make native close and configure calls 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static NativeDispatcher nd; 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Our file descriptor 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final FileDescriptor fd; 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // fd value needed for dev/poll. This value will remain valid 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // even after the value in the file descriptor object has been set to -1 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int fdVal; 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ID of native thread currently blocked in this channel, for signalling 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private volatile long thread = 0; 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Lock held by thread currently blocked in this channel 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Object lock = new Object(); 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Lock held by any thread that modifies the state fields declared below 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // DO NOT invoke a blocking I/O operation while holding this lock! 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Object stateLock = new Object(); 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- The following fields are protected by stateLock 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Channel state, increases monotonically 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int ST_UNINITIALIZED = -1; 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int ST_INUSE = 0; 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int ST_KILLED = 1; 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int state = ST_UNINITIALIZED; 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Binding 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private InetSocketAddress localAddress; // null => unbound 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // set true when exclusive binding is on and SO_REUSEADDR is emulated 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean isReuseAddress; 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Our socket adaptor, if any 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ServerSocket socket; 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- End of fields protected by stateLock 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ServerSocketChannelImpl(SelectorProvider sp) throws IOException { 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(sp); 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fd = Net.serverSocket(true); 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fdVal = IOUtil.fdVal(fd); 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.state = ST_INUSE; 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ServerSocketChannelImpl(SelectorProvider sp, 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FileDescriptor fd, 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean bound) 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(sp); 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fd = fd; 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fdVal = IOUtil.fdVal(fd); 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.state = ST_INUSE; 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bound) 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski localAddress = Net.localAddress(fd); 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public ServerSocket socket() { 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (socket == null) 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski socket = ServerSocketAdaptor.create(this); 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return socket; 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SocketAddress getLocalAddress() throws IOException { 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return localAddress == null? localAddress 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski : Net.getRevealedLocalAddress( 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.asInetSocketAddress(localAddress)); 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public <T> ServerSocketChannel setOption(SocketOption<T> name, T value) 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == null) 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!supportedOptions().contains(name)) 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UnsupportedOperationException("'" + name + "' not supported"); 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == StandardSocketOptions.SO_REUSEADDR && 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.useExclusiveBind()) 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // SO_REUSEADDR emulated when using exclusive bind 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isReuseAddress = (Boolean)value; 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // no options that require special handling 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.setSocketOption(fd, Net.UNSPEC, name, value); 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @SuppressWarnings("unchecked") 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public <T> T getOption(SocketOption<T> name) 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == null) 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!supportedOptions().contains(name)) 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UnsupportedOperationException("'" + name + "' not supported"); 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == StandardSocketOptions.SO_REUSEADDR && 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.useExclusiveBind()) 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // SO_REUSEADDR emulated when using exclusive bind 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (T)Boolean.valueOf(isReuseAddress); 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // no options that require special handling 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (T) Net.getSocketOption(fd, Net.UNSPEC, name); 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static class DefaultOptionsHolder { 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static final Set<SocketOption<?>> defaultOptions = defaultOptions(); 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static Set<SocketOption<?>> defaultOptions() { 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(2); 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.SO_RCVBUF); 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.SO_REUSEADDR); 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Collections.unmodifiableSet(set); 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final Set<SocketOption<?>> supportedOptions() { 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return DefaultOptionsHolder.defaultOptions; 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isBound() { 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return localAddress != null; 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public InetSocketAddress localAddress() { 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return localAddress; 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public ServerSocketChannel bind(SocketAddress local, int backlog) throws IOException { 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lock) { 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isBound()) 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new AlreadyBoundException(); 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress isa = (local == null) ? new InetSocketAddress(0) : 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.checkAddress(local); 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager sm = System.getSecurityManager(); 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sm != null) 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sm.checkListen(isa.getPort()); 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort()); 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.bind(fd, isa.getAddress(), isa.getPort()); 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.listen(fd, backlog < 1 ? 50 : backlog); 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski localAddress = Net.localAddress(fd); 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SocketChannel accept() throws IOException { 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lock) { 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isBound()) 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NotYetBoundException(); 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SocketChannel sc = null; 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 0; 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FileDescriptor newfd = new FileDescriptor(); 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress[] isaa = new InetSocketAddress[1]; 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski thread = NativeThread.current(); 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (;;) { 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = accept0(this.fd, newfd, isaa); 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((n == IOStatus.INTERRUPTED) && isOpen()) 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski thread = 0; 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(n > 0); 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n < 1) 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski IOUtil.configureBlocking(newfd, true); 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress isa = isaa[0]; 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sc = new SocketChannelImpl(provider(), newfd, isa); 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager sm = System.getSecurityManager(); 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sm != null) { 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sm.checkAccept(isa.getAddress().getHostAddress(), 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isa.getPort()); 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (SecurityException x) { 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sc.close(); 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw x; 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return sc; 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void implConfigureBlocking(boolean block) throws IOException { 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski IOUtil.configureBlocking(fd, block); 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void implCloseSelectableChannel() throws IOException { 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state != ST_KILLED) 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nd.preClose(fd); 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long th = thread; 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (th != 0) 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski NativeThread.signal(th); 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isRegistered()) 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski kill(); 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void kill() throws IOException { 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state == ST_KILLED) 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state == ST_UNINITIALIZED) { 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski state = ST_KILLED; 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert !isOpen() && !isRegistered(); 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nd.close(fd); 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski state = ST_KILLED; 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Translates native poll revent set into a ready operation set 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean translateReadyOps(int ops, int initialOps, 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SelectionKeyImpl sk) { 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int intOps = sk.nioInterestOps(); // Do this just once, it synchronizes 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int oldOps = sk.nioReadyOps(); 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int newOps = initialOps; 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((ops & PollArrayWrapper.POLLNVAL) != 0) { 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // This should only happen if this channel is pre-closed while a 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // selection operation is in progress 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ## Throw an error if this channel has not been pre-closed 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((ops & (PollArrayWrapper.POLLERR 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski | PollArrayWrapper.POLLHUP)) != 0) { 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newOps = intOps; 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sk.nioReadyOps(newOps); 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (newOps & ~oldOps) != 0; 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (((ops & PollArrayWrapper.POLLIN) != 0) && 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((intOps & SelectionKey.OP_ACCEPT) != 0)) 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newOps |= SelectionKey.OP_ACCEPT; 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sk.nioReadyOps(newOps); 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (newOps & ~oldOps) != 0; 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) { 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return translateReadyOps(ops, sk.nioReadyOps(), sk); 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) { 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return translateReadyOps(ops, 0, sk); 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Translates an interest operation set into a native poll event set 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) { 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int newOps = 0; 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Translate ops 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((ops & SelectionKey.OP_ACCEPT) != 0) 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newOps |= PollArrayWrapper.POLLIN; 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Place ops into pollfd array 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sk.selector.putEventOps(sk, newOps); 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public FileDescriptor getFD() { 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return fd; 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getFDVal() { 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return fdVal; 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String toString() { 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski StringBuffer sb = new StringBuffer(); 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append(this.getClass().getName()); 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append('['); 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) { 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append("closed"); 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress addr = localAddress(); 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (addr == null) { 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append("unbound"); 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append(Net.getRevealedLocalAddressAsString(addr)); 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append(']'); 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return sb.toString(); 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- Native methods -- 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Accepts a new connection, setting the given file descriptor to refer to 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the new socket and setting isaa[0] to the socket's remote address. 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Returns 1 on success, or IOStatus.UNAVAILABLE (if non-blocking and no 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // connections are pending) or IOStatus.INTERRUPTED. 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private native int accept0(FileDescriptor ssfd, FileDescriptor newfd, 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress[] isaa) 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException; 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static native void initIDs(); 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static { 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initIDs(); 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nd = new SocketDispatcher(); 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 402