src/jdk.net/linux/classes/jdk/internal/net/rdma/RdmaServerSocketChannelImpl.java
author bpb
Wed, 06 Feb 2019 12:48:01 -0800
branchrsocket-branch
changeset 57156 81e4a12fd1a4
parent 57115 512e7cc6ccce
child 57160 c502c299d41e
permissions -rw-r--r--
rsocket-branch: change recent copyright year to 2019 and new files to 2019 only
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
57115
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
     1
/*
57156
81e4a12fd1a4 rsocket-branch: change recent copyright year to 2019 and new files to 2019 only
bpb
parents: 57115
diff changeset
     2
 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
57115
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
     4
 *
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    10
 *
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    15
 * accompanied this code).
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    16
 *
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    20
 *
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    23
 * questions.
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    24
 */
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    25
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    26
package jdk.internal.net.rdma;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    27
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    28
import java.io.FileDescriptor;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    29
import java.io.IOException;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    30
import java.net.InetAddress;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    31
import java.net.InetSocketAddress;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    32
import java.net.ProtocolFamily;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    33
import java.net.ServerSocket;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    34
import java.net.SocketAddress;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    35
import java.net.SocketOption;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    36
import java.net.StandardSocketOptions;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    37
import java.net.StandardProtocolFamily;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    38
import java.nio.channels.AlreadyBoundException;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    39
import java.nio.channels.AsynchronousCloseException;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    40
import java.nio.channels.ClosedChannelException;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    41
import java.nio.channels.NotYetBoundException;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    42
import java.nio.channels.SelectionKey;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    43
import java.nio.channels.ServerSocketChannel;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    44
import java.nio.channels.SocketChannel;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    45
import java.nio.channels.UnsupportedAddressTypeException;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    46
import java.nio.channels.spi.SelectorProvider;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    47
import java.util.Collections;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    48
import java.util.HashSet;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    49
import java.util.Objects;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    50
import java.util.Set;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    51
import java.util.concurrent.locks.ReentrantLock;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    52
import sun.nio.ch.IOStatus;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    53
import sun.nio.ch.IOUtil;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    54
import sun.nio.ch.NativeThread;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    55
import sun.nio.ch.Net;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    56
import sun.nio.ch.SelChImpl;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    57
import sun.nio.ch.SelectionKeyImpl;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    58
import sun.net.ext.RdmaSocketOptions;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    59
import static java.net.StandardProtocolFamily.INET;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    60
import static java.net.StandardProtocolFamily.INET6;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    61
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    62
public class RdmaServerSocketChannelImpl
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    63
    extends ServerSocketChannel
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    64
    implements SelChImpl
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    65
{
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    66
    //The protocol family of the socket
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    67
    private final ProtocolFamily family;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    68
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    69
    private static RdmaSocketDispatcher nd;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    70
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    71
    private final FileDescriptor fd;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    72
    private final int fdVal;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    73
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    74
    private final ReentrantLock acceptLock = new ReentrantLock();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    75
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    76
    private final Object stateLock = new Object();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    77
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    78
    private static final int ST_INUSE = 0;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    79
    private static final int ST_CLOSING = 1;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    80
    private static final int ST_KILLPENDING = 2;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    81
    private static final int ST_KILLED = 3;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    82
    private int state;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    83
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    84
    private long thread;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    85
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    86
    private InetSocketAddress localAddress;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    87
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    88
    private boolean isReuseAddress;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    89
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    90
    private ServerSocket socket;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    91
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    92
    private static final UnsupportedOperationException unsupported;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    93
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    94
    private static final SelectorProvider checkSupported(SelectorProvider sp) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    95
        if (unsupported != null)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    96
            throw new UnsupportedOperationException(unsupported.getMessage(), unsupported);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    97
        else
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    98
            return sp;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    99
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   100
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   101
    RdmaServerSocketChannelImpl(SelectorProvider sp, ProtocolFamily family)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   102
            throws IOException {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   103
        super(checkSupported(sp));
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   104
        Objects.requireNonNull(family, "'family' is null");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   105
        if (!(family == INET || family == INET6)) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   106
            throw new UnsupportedOperationException(
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   107
                    "Protocol family not supported");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   108
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   109
        if (family == INET6) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   110
            if (!Net.isIPv6Available()) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   111
                throw new UnsupportedOperationException(
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   112
                        "IPv6 not available");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   113
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   114
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   115
        this.family = family;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   116
        this.fd = RdmaNet.serverSocket(family, true);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   117
        this.fdVal = IOUtil.fdVal(fd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   118
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   119
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   120
    private void ensureOpen() throws ClosedChannelException {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   121
        if (!isOpen())
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   122
            throw new ClosedChannelException();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   123
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   124
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   125
    @Override
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   126
    public ServerSocket socket() {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   127
        synchronized (stateLock) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   128
            if (socket == null)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   129
                socket = RdmaServerSocketAdaptor.create(this);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   130
            return socket;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   131
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   132
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   133
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   134
    @Override
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   135
    public SocketAddress getLocalAddress() throws IOException {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   136
        synchronized (stateLock) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   137
            ensureOpen();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   138
            return (localAddress == null)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   139
                    ? null
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   140
                    : Net.getRevealedLocalAddress(localAddress);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   141
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   142
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   143
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   144
    @Override
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   145
    public <T> ServerSocketChannel setOption(SocketOption<T> name, T value)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   146
            throws IOException
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   147
    {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   148
        Objects.requireNonNull(name);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   149
        if (!supportedOptions().contains(name))
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   150
            throw new UnsupportedOperationException("'" + name
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   151
                    + "' not supported");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   152
        synchronized (stateLock) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   153
            ensureOpen();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   154
            if (isBound() && (name == StandardSocketOptions.SO_REUSEADDR))
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   155
                throw new UnsupportedOperationException(
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   156
                        "RDMA server socket channel cannot set the socket option "
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   157
                        + name.toString() + " after bind.");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   158
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   159
            RdmaNet.setSocketOption(fd, RdmaNet.UNSPEC, name, value);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   160
            return this;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   161
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   162
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   163
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   164
    @Override
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   165
    @SuppressWarnings("unchecked")
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   166
    public <T> T getOption(SocketOption<T> name)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   167
            throws IOException
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   168
    {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   169
        Objects.requireNonNull(name);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   170
        if (!supportedOptions().contains(name))
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   171
            throw new UnsupportedOperationException("'" + name
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   172
                    + "' not supported");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   173
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   174
        synchronized (stateLock) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   175
            ensureOpen();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   176
            return (T) RdmaNet.getSocketOption(fd, RdmaNet.UNSPEC, name);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   177
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   178
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   179
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   180
    private static class DefaultOptionsHolder {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   181
        static final Set<SocketOption<?>> defaultOptions = defaultOptions();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   182
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   183
        private static Set<SocketOption<?>> defaultOptions() {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   184
            HashSet<SocketOption<?>> set = new HashSet<>(2);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   185
            set.add(StandardSocketOptions.SO_RCVBUF);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   186
            set.add(StandardSocketOptions.SO_REUSEADDR);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   187
            if (RdmaNet.isRdmaAvailable()) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   188
                RdmaSocketOptions rdmaOptions =
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   189
                        RdmaSocketOptions.getInstance();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   190
                set.addAll(rdmaOptions.options());
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   191
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   192
            return Collections.unmodifiableSet(set);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   193
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   194
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   195
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   196
    public final Set<SocketOption<?>> supportedOptions() {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   197
        return DefaultOptionsHolder.defaultOptions;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   198
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   199
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   200
    private final InetSocketAddress anyLocalAddress() throws IOException {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   201
        if (family == INET)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   202
            return new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   203
        else if (family == INET6)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   204
            return new InetSocketAddress(InetAddress.getByName("::"), 0);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   205
        else
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   206
            throw new UnsupportedAddressTypeException();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   207
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   208
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   209
    @Override
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   210
    public ServerSocketChannel bind(SocketAddress local, int backlog)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   211
            throws IOException {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   212
        synchronized (stateLock) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   213
            ensureOpen();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   214
            if (localAddress != null)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   215
                throw new AlreadyBoundException();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   216
            InetSocketAddress isa = (local == null)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   217
                                    ? anyLocalAddress()
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   218
                                    : RdmaNet.checkAddress(local, family);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   219
            SecurityManager sm = System.getSecurityManager();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   220
            if (sm != null)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   221
                sm.checkListen(isa.getPort());
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   222
            RdmaNet.bind(family, fd, isa.getAddress(), isa.getPort());
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   223
            RdmaNet.listen(fd, backlog < 1 ? 50 : backlog);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   224
            localAddress = RdmaNet.localAddress(fd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   225
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   226
        return this;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   227
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   228
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   229
    private void begin(boolean blocking) throws ClosedChannelException {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   230
        if (blocking)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   231
            begin();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   232
        synchronized (stateLock) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   233
            ensureOpen();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   234
            if (localAddress == null)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   235
                throw new NotYetBoundException();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   236
            if (blocking)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   237
                thread = NativeThread.current();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   238
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   239
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   240
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   241
    private void end(boolean blocking, boolean completed)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   242
            throws AsynchronousCloseException {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   243
        if (blocking) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   244
            synchronized (stateLock) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   245
                thread = 0;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   246
                if (state == ST_CLOSING) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   247
                    stateLock.notifyAll();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   248
                }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   249
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   250
            end(completed);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   251
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   252
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   253
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   254
    @Override
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   255
    public SocketChannel accept() throws IOException {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   256
        acceptLock.lock();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   257
        try {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   258
            int n = 0;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   259
            FileDescriptor newfd = new FileDescriptor();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   260
            InetSocketAddress[] isaa = new InetSocketAddress[1];
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   261
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   262
            boolean blocking = isBlocking();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   263
            try {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   264
                begin(blocking);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   265
                do {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   266
                    if (blocking) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   267
                        do {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   268
                            n  = checkAccept(this.fd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   269
                        } while ((n == 0 || n == IOStatus.INTERRUPTED)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   270
                                && isOpen());
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   271
                    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   272
                    n = accept(this.fd, newfd, isaa);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   273
                } while (n == IOStatus.INTERRUPTED && isOpen());
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   274
            } finally {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   275
                end(blocking, n > 0);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   276
                assert IOStatus.check(n);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   277
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   278
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   279
            if (n < 1)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   280
                return null;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   281
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   282
            // newly accepted socket is initially in blocking mode
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   283
            RdmaNet.configureBlocking(newfd, true);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   284
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   285
            InetSocketAddress isa = isaa[0];
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   286
            SocketChannel sc = new RdmaSocketChannelImpl(provider(),
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   287
                    newfd, isa);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   288
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   289
            // check permitted to accept connections from the remote address
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   290
            SecurityManager sm = System.getSecurityManager();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   291
            if (sm != null) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   292
                try {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   293
                    sm.checkAccept(isa.getAddress().getHostAddress(),
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   294
                            isa.getPort());
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   295
                } catch (SecurityException x) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   296
                    sc.close();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   297
                    throw x;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   298
                }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   299
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   300
            return sc;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   301
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   302
        } finally {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   303
            acceptLock.unlock();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   304
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   305
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   306
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   307
    @Override
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   308
    protected void implConfigureBlocking(boolean block) throws IOException {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   309
        acceptLock.lock();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   310
        try {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   311
            synchronized (stateLock) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   312
                ensureOpen();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   313
                RdmaNet.configureBlocking(fd, block);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   314
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   315
        } finally {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   316
            acceptLock.unlock();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   317
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   318
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   319
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   320
    @Override
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   321
    protected void implCloseSelectableChannel() throws IOException {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   322
        assert !isOpen();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   323
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   324
        boolean interrupted = false;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   325
        boolean blocking;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   326
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   327
        // set state to ST_CLOSING
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   328
        synchronized (stateLock) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   329
            assert state < ST_CLOSING;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   330
            state = ST_CLOSING;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   331
            blocking = isBlocking();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   332
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   333
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   334
        // wait for any outstanding accept to complete
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   335
        if (blocking) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   336
            synchronized (stateLock) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   337
                assert state == ST_CLOSING;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   338
                long th = thread;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   339
                if (th != 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   340
                    nd.preClose(fd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   341
                    NativeThread.signal(th);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   342
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   343
                    // wait for accept operation to end
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   344
                    while (thread != 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   345
                        try {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   346
                            stateLock.wait();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   347
                        } catch (InterruptedException e) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   348
                            interrupted = true;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   349
                        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   350
                    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   351
                }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   352
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   353
        } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   354
            // non-blocking mode: wait for accept to complete
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   355
            acceptLock.lock();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   356
            acceptLock.unlock();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   357
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   358
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   359
        // set state to ST_KILLPENDING
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   360
        synchronized (stateLock) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   361
            assert state == ST_CLOSING;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   362
            state = ST_KILLPENDING;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   363
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   364
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   365
        // close socket if not registered with Selector
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   366
        if (!isRegistered())
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   367
            kill();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   368
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   369
        // restore interrupt status
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   370
        if (interrupted)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   371
            Thread.currentThread().interrupt();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   372
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   373
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   374
    @Override
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   375
    public void kill() throws IOException {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   376
        synchronized (stateLock) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   377
            if (state == ST_KILLPENDING) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   378
                state = ST_KILLED;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   379
                nd.close(fd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   380
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   381
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   382
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   383
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   384
    boolean isBound() {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   385
        synchronized (stateLock) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   386
            return localAddress != null;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   387
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   388
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   389
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   390
    InetSocketAddress localAddress() {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   391
        synchronized (stateLock) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   392
            return localAddress;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   393
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   394
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   395
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   396
    /**
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   397
     * Poll this channel's socket for a new connection up to the given timeout.
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   398
     * @return {@code true} if there is a connection to accept
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   399
     */
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   400
    boolean pollAccept(long timeout) throws IOException {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   401
        assert Thread.holdsLock(blockingLock()) && isBlocking();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   402
        acceptLock.lock();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   403
        try {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   404
            boolean polled = false;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   405
            try {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   406
                begin(true);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   407
                int events = RdmaNet.poll(fd, Net.POLLIN, timeout);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   408
                polled = (events != 0);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   409
            } finally {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   410
                end(true, polled);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   411
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   412
            return polled;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   413
        } finally {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   414
            acceptLock.unlock();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   415
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   416
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   417
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   418
    public boolean translateReadyOps(int ops, int initialOps,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   419
            SelectionKeyImpl ski) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   420
        int intOps = ski.nioInterestOps();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   421
        int oldOps = ski.nioReadyOps();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   422
        int newOps = initialOps;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   423
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   424
        if ((ops & Net.POLLNVAL) != 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   425
            return false;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   426
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   427
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   428
        if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   429
            newOps = intOps;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   430
            ski.nioReadyOps(newOps);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   431
            return (newOps & ~oldOps) != 0;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   432
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   433
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   434
        if (((ops & Net.POLLIN) != 0) &&
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   435
            ((intOps & SelectionKey.OP_ACCEPT) != 0))
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   436
                newOps |= SelectionKey.OP_ACCEPT;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   437
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   438
        ski.nioReadyOps(newOps);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   439
        return (newOps & ~oldOps) != 0;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   440
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   441
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   442
    public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl ski) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   443
        return translateReadyOps(ops, ski.nioReadyOps(), ski);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   444
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   445
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   446
    public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl ski) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   447
        return translateReadyOps(ops, 0, ski);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   448
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   449
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   450
    public int translateInterestOps(int ops) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   451
        int newOps = 0;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   452
        if ((ops & SelectionKey.OP_ACCEPT) != 0)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   453
            newOps |= Net.POLLIN;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   454
        return newOps;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   455
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   456
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   457
    public FileDescriptor getFD() {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   458
        return fd;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   459
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   460
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   461
    public int getFDVal() {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   462
        return fdVal;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   463
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   464
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   465
    public String toString() {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   466
        StringBuilder sb = new StringBuilder();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   467
        sb.append(this.getClass().getName());
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   468
        sb.append('[');
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   469
        if (!isOpen()) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   470
            sb.append("closed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   471
        } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   472
            synchronized (stateLock) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   473
                InetSocketAddress addr = localAddress;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   474
                if (addr == null) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   475
                    sb.append("unbound");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   476
                } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   477
                    sb.append(Net.getRevealedLocalAddressAsString(addr));
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   478
                }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   479
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   480
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   481
        sb.append(']');
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   482
        return sb.toString();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   483
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   484
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   485
    private int accept(FileDescriptor ssfd, FileDescriptor newfd,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   486
            InetSocketAddress[] isaa) throws IOException {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   487
        return accept0(ssfd, newfd, isaa);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   488
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   489
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   490
    // -- Native methods --
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   491
    private static native int checkAccept(FileDescriptor fd)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   492
            throws IOException;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   493
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   494
    private native int accept0(FileDescriptor ssfd, FileDescriptor newfd,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   495
            InetSocketAddress[] isaa) throws IOException;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   496
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   497
    private static native void initIDs()throws UnsupportedOperationException;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   498
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   499
    static {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   500
        IOUtil.load();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   501
        System.loadLibrary("extnet");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   502
        UnsupportedOperationException uoe = null;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   503
        try {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   504
            initIDs();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   505
        } catch (UnsupportedOperationException e) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   506
            uoe = e;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   507
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   508
        unsupported = uoe;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   509
        nd = new RdmaSocketDispatcher();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   510
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   511
}