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