src/jdk.net/linux/native/libextnet/RdmaSocketImpl.c
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
#include "java_net_SocketOptions.h"
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    27
#include "jdk_internal_net_rdma_RdmaSocketImpl.h"
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    28
#include "jvm.h"
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    29
#include "net_util.h"
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    30
#include "rdma_util_md.h"
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    31
#include "Rsocket.h"
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    32
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    33
/************************************************************************
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    34
 * RdmaSocketImpl
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    35
 */
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    36
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    37
static jfieldID IO_fd_fdID;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    38
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    39
jfieldID psi_fdID;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    40
jfieldID psi_addressID;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    41
jfieldID psi_ipaddressID;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    42
jfieldID psi_portID;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    43
jfieldID psi_localportID;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    44
jfieldID psi_timeoutID;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    45
jfieldID psi_trafficClassID;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    46
jfieldID psi_serverSocketID;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    47
jfieldID psi_fdLockID;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    48
jfieldID psi_closePendingID;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    49
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    50
#define SET_NONBLOCKING(fd) {           \
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    51
        int flags = rs_fcntl(fd, F_GETFL); \
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    52
        flags |= O_NONBLOCK;            \
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    53
        rs_fcntl(fd, F_SETFL, flags);      \
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    54
}
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    55
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    56
#define SET_BLOCKING(fd) {              \
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    57
        int flags = rs_fcntl(fd, F_GETFL); \
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    58
        flags &= ~O_NONBLOCK;           \
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    59
        rs_fcntl(fd, F_SETFL, flags);      \
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    60
}
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    61
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    62
static jclass socketExceptionCls;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    63
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    64
static int getFD(JNIEnv *env, jobject this) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    65
    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    66
    CHECK_NULL_RETURN(fdObj, -1);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    67
    return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    68
}
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    69
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    70
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    71
jfieldID
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    72
NET_GetFileDescriptorID(JNIEnv *env) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    73
    jclass cls = (*env)->FindClass(env, "java/io/FileDescriptor");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    74
    CHECK_NULL_RETURN(cls, NULL);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    75
    return (*env)->GetFieldID(env, cls, "fd", "I");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    76
}
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    77
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    78
JNIEXPORT void JNICALL
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    79
Java_jdk_internal_net_rdma_RdmaSocketImpl_initProto(JNIEnv *env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    80
        jclass cls) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    81
    loadRdmaFuncs(env);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    82
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    83
    jclass clazz = (*env)->FindClass(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    84
            "jdk/internal/net/rdma/RdmaSocketImpl");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    85
    psi_fdID = (*env)->GetFieldID(env, clazz , "fd",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    86
            "Ljava/io/FileDescriptor;");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    87
    CHECK_NULL(psi_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    88
    psi_addressID = (*env)->GetFieldID(env, clazz, "address",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    89
            "Ljava/net/InetAddress;");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    90
    CHECK_NULL(psi_addressID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    91
    psi_timeoutID = (*env)->GetFieldID(env, clazz, "timeout", "I");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    92
    CHECK_NULL(psi_timeoutID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    93
    psi_trafficClassID = (*env)->GetFieldID(env, clazz, "trafficClass", "I");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    94
    CHECK_NULL(psi_trafficClassID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    95
    psi_portID = (*env)->GetFieldID(env, clazz, "port", "I");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    96
    CHECK_NULL(psi_portID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    97
    psi_localportID = (*env)->GetFieldID(env, clazz, "localport", "I");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    98
    CHECK_NULL(psi_localportID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
    99
    psi_serverSocketID = (*env)->GetFieldID(env, clazz, "serverSocket",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   100
                        "Ljava/net/ServerSocket;");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   101
    CHECK_NULL(psi_serverSocketID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   102
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   103
    IO_fd_fdID = NET_GetFileDescriptorID(env);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   104
    CHECK_NULL(IO_fd_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   105
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   106
    initInetAddressIDs(env);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   107
    JNU_CHECK_EXCEPTION(env);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   108
}
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   109
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   110
JNIEXPORT jboolean JNICALL
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   111
Java_jdk_internal_net_rdma_RdmaSocketImpl_isRdmaAvailable0(JNIEnv *env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   112
        jclass cls) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   113
    return rdma_supported();
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   114
}
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   115
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   116
void
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   117
NET_SetTrafficClass(SOCKETADDRESS *sa, int trafficClass) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   118
    if (sa->sa.sa_family == AF_INET6) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   119
        sa->sa6.sin6_flowinfo = htonl((trafficClass & 0xff) << 20);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   120
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   121
}
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   122
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   123
/*
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   124
 * Class:     jdk_net_RdmaSocketImpl
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   125
 * Method:    rdmaSocketCreate
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   126
 * Signature: (Z)V */
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   127
JNIEXPORT void JNICALL
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   128
Java_jdk_internal_net_rdma_RdmaSocketImpl_rdmaSocketCreate(JNIEnv *env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   129
        jclass cls, jboolean preferIPv6, jboolean stream) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   130
    jobject fdObj, ssObj;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   131
    int fd;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   132
    int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   133
    int domain = (ipv6_available() && preferIPv6) ? AF_INET6 : AF_INET;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   134
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   135
    if (socketExceptionCls == NULL) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   136
        jclass c = (*env)->FindClass(env, "java/net/SocketException");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   137
        CHECK_NULL(c);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   138
        socketExceptionCls = (jclass)(*env)->NewGlobalRef(env, c);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   139
        CHECK_NULL(socketExceptionCls);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   140
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   141
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   142
    fdObj = (*env)->GetObjectField(env, cls, psi_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   143
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   144
    if (fdObj == NULL) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   145
        (*env)->ThrowNew(env, socketExceptionCls, "null fd object");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   146
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   147
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   148
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   149
    if ((fd = rs_socket(domain, type, 0)) == -1) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   150
        NET_ThrowNew(env, errno, "can't create socket");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   151
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   152
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   153
    if (domain == AF_INET6) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   154
        int arg = 0;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   155
        if (rs_setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   156
                       sizeof(int)) < 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   157
            NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   158
            rs_close(fd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   159
            return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   160
        }
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
    ssObj = (*env)->GetObjectField(env, cls, psi_serverSocketID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   164
    if (ssObj != NULL) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   165
        int arg = 1;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   166
        SET_NONBLOCKING(fd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   167
        if (RDMA_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   168
                       sizeof(arg)) < 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   169
            NET_ThrowNew(env, errno, "cannot set SO_REUSEADDR");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   170
            rs_close(fd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   171
            return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   172
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   173
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   174
    (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   175
}
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   176
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   177
JNIEXPORT void JNICALL
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   178
Java_jdk_internal_net_rdma_RdmaSocketImpl_rdmaSocketConnect(JNIEnv *env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   179
        jclass cls, jboolean preferIPv6, jobject iaObj, jint port,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   180
        jint timeout) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   181
    jint localport = (*env)->GetIntField(env, cls, psi_localportID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   182
    int len = 0;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   183
    jobject fdObj = (*env)->GetObjectField(env, cls, psi_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   184
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   185
    jobject fdLock;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   186
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   187
    jint trafficClass = (*env)->GetIntField(env, cls, psi_trafficClassID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   188
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   189
    jint fd;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   190
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   191
    SOCKETADDRESS sa;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   192
    int connect_rv = -1;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   193
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   194
    if (IS_NULL(fdObj)) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   195
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   196
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   197
    } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   198
        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   199
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   200
    if (IS_NULL(iaObj)) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   201
        JNU_ThrowNullPointerException(env, "inet address argument null.");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   202
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   203
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   204
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   205
    if (NET_InetAddressToSockaddr(env, iaObj, port, &sa, &len,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   206
            preferIPv6) != 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   207
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   208
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   209
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   210
    if (trafficClass != 0 && ipv6_available()) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   211
        NET_SetTrafficClass(&sa, trafficClass);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   212
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   213
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   214
    if (timeout <= 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   215
        connect_rv = RDMA_Connect(fd, &sa.sa, len);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   216
    } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   217
        SET_NONBLOCKING(fd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   218
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   219
        connect_rv = rs_connect(fd, &sa.sa, len);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   220
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   221
        if (connect_rv != 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   222
            socklen_t optlen;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   223
            jlong nanoTimeout = (jlong) timeout * NET_NSEC_PER_MSEC;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   224
            jlong prevNanoTime = JVM_NanoTime(env, 0);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   225
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   226
            if (errno != EINPROGRESS) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   227
                JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   228
                        JNU_JAVANETPKG "ConnectException", "connect failed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   229
                SET_BLOCKING(fd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   230
                return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   231
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   232
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   233
            while (1) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   234
                jlong newNanoTime;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   235
                struct pollfd pfd;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   236
                pfd.fd = fd;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   237
                pfd.events = POLLOUT;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   238
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   239
                errno = 0;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   240
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   241
                connect_rv = RDMA_Poll(&pfd, 1, nanoTimeout / NET_NSEC_PER_MSEC);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   242
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   243
                if (connect_rv >= 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   244
                    break;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   245
                }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   246
                if (errno != EINTR) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   247
                    break;
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
                newNanoTime = JVM_NanoTime(env, 0);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   251
                nanoTimeout -= (newNanoTime - prevNanoTime);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   252
                if (nanoTimeout < NET_NSEC_PER_MSEC) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   253
                    connect_rv = 0;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   254
                    break;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   255
                }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   256
                prevNanoTime = newNanoTime;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   257
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   258
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   259
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   260
            if (connect_rv == 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   261
                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   262
                        "connect timed out");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   263
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   264
                SET_BLOCKING(fd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   265
                rs_shutdown(fd, 2);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   266
                return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   267
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   268
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   269
            optlen = sizeof(connect_rv);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   270
            if (rs_getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   271
                            &optlen) <0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   272
                connect_rv = errno;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   273
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   274
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   275
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   276
        SET_BLOCKING(fd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   277
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   278
        if (connect_rv != 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   279
            errno = connect_rv;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   280
            connect_rv = -1;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   281
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   282
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   283
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   284
    if (connect_rv < 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   285
        if (connect_rv == -1 && errno == EINVAL) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   286
            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   287
                "Invalid argument or cannot assign requested address");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   288
            return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   289
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   290
#if defined(EPROTO)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   291
        if (errno == EPROTO) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   292
            JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   293
                    JNU_JAVANETPKG "ProtocolException", "Protocol error");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   294
            return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   295
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   296
#endif
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   297
        if (errno == ECONNREFUSED) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   298
            JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   299
                    JNU_JAVANETPKG "ConnectException", "Connection refused");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   300
        } else if (errno == ETIMEDOUT) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   301
            JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   302
                    JNU_JAVANETPKG "ConnectException", "Connection timed out");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   303
        } else if (errno == EHOSTUNREACH) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   304
            JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   305
                    JNU_JAVANETPKG "NoRouteToHostException", "Host unreachable");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   306
        } else if (errno == EADDRNOTAVAIL) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   307
            JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   308
                    JNU_JAVANETPKG "NoRouteToHostException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   309
                    "Address not available");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   310
        } else if ((errno == EISCONN) || (errno == EBADF)) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   311
            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   312
                    "Socket closed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   313
        } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   314
            JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   315
                    JNU_JAVANETPKG "SocketException", "connect failed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   316
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   317
        return;
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
    (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   321
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   322
    (*env)->SetObjectField(env, cls, psi_addressID, iaObj);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   323
    (*env)->SetIntField(env, cls, psi_portID, port);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   324
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   325
    if (localport == 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   326
        socklen_t slen = sizeof(SOCKETADDRESS);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   327
        if (rs_getsockname(fd, &sa.sa, &slen) == -1) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   328
            JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   329
                    JNU_JAVANETPKG "SocketException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   330
                    "Error getting socket name");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   331
        } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   332
            localport = NET_GetPortFromSockaddr(&sa);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   333
            (*env)->SetIntField(env, cls, psi_localportID, localport);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   334
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   335
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   336
}
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   337
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   338
JNIEXPORT void JNICALL
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   339
Java_jdk_internal_net_rdma_RdmaSocketImpl_rdmaSocketBind(JNIEnv *env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   340
        jclass cls, jboolean preferIPv6, jobject iaObj, jint localport) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   341
    jobject fdObj = (*env)->GetObjectField(env, cls, psi_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   342
    int fd;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   343
    int len = 0;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   344
    SOCKETADDRESS sa;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   345
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   346
    if (IS_NULL(fdObj)) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   347
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   348
                        "Socket closed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   349
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   350
    } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   351
        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   352
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   353
    if (IS_NULL(iaObj)) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   354
        JNU_ThrowNullPointerException(env, "iaObj is null.");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   355
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   356
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   357
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   358
    if (NET_InetAddressToSockaddr(env, iaObj, localport, &sa,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   359
                                  &len, preferIPv6) != 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   360
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   361
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   362
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   363
    if (RDMA_Bind(fd, &sa, len) < 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   364
        if (errno == EADDRINUSE || errno == EADDRNOTAVAIL ||
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   365
            errno == EPERM || errno == EACCES) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   366
            JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   367
                    JNU_JAVANETPKG "BindException", "Bind failed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   368
        } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   369
            JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   370
                    JNU_JAVANETPKG "SocketException", "Bind failed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   371
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   372
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   373
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   374
    (*env)->SetObjectField(env, cls, psi_addressID, iaObj);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   375
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   376
    if (localport == 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   377
        socklen_t slen = sizeof(SOCKETADDRESS);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   378
        if (rs_getsockname(fd, &sa.sa, &slen) == -1) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   379
            JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   380
                    JNU_JAVANETPKG "SocketException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   381
                    "Error getting socket name");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   382
            return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   383
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   384
        localport = NET_GetPortFromSockaddr(&sa);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   385
        (*env)->SetIntField(env, cls, psi_localportID, localport);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   386
    } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   387
        (*env)->SetIntField(env, cls, psi_localportID, localport);
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
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   391
JNIEXPORT void JNICALL
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   392
Java_jdk_internal_net_rdma_RdmaSocketImpl_rdmaSocketListen(JNIEnv *env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   393
        jclass cls, jint count) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   394
    jobject fdObj = (*env)->GetObjectField(env, cls, psi_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   395
    int fd;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   396
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   397
    if (IS_NULL(fdObj)) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   398
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   399
                "Socket closed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   400
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   401
    } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   402
        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   403
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   404
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   405
    if (count == 0x7fffffff)
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   406
        count -= 1;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   407
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   408
    int rv = rs_listen(fd, count);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   409
    if (rv == -1) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   410
        JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   411
                JNU_JAVANETPKG "SocketException", "Listen failed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   412
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   413
}
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   414
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   415
JNIEXPORT void JNICALL
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   416
Java_jdk_internal_net_rdma_RdmaSocketImpl_rdmaSocketAccept(JNIEnv *env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   417
        jclass cls, jobject socket) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   418
    int port;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   419
    jint timeout = (*env)->GetIntField(env, cls, psi_timeoutID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   420
    jlong prevNanoTime = 0;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   421
    jlong nanoTimeout = (jlong) timeout * NET_NSEC_PER_MSEC;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   422
    jobject fdObj = (*env)->GetObjectField(env, cls, psi_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   423
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   424
    jobject socketFdObj;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   425
    jobject socketAddressObj;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   426
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   427
    jint fd;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   428
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   429
    jint newfd;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   430
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   431
    SOCKETADDRESS sa;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   432
    socklen_t slen = sizeof(SOCKETADDRESS);
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 (IS_NULL(fdObj)) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   435
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   436
                "Socket closed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   437
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   438
    } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   439
        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   440
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   441
    if (IS_NULL(socket)) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   442
        JNU_ThrowNullPointerException(env, "socket is null");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   443
        return;
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
    for (;;) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   447
        int ret;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   448
        jlong currNanoTime;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   449
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   450
        if (prevNanoTime == 0 && nanoTimeout > 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   451
            prevNanoTime = JVM_NanoTime(env, 0);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   452
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   453
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   454
        if (timeout <= 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   455
            ret = RDMA_Timeout(env, fd, -1, 0);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   456
        } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   457
            ret = RDMA_Timeout(env, fd, nanoTimeout / NET_NSEC_PER_MSEC,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   458
                    prevNanoTime);
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
        if (ret == 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   462
            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   463
                    "Accept timed out");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   464
            return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   465
        } else if (ret == -1) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   466
            if (errno == EBADF) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   467
               JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   468
                       "Socket closed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   469
            } else if (errno == ENOMEM) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   470
               JNU_ThrowOutOfMemoryError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   471
                       "NET_Timeout native heap allocation failed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   472
            } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   473
               JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   474
                       JNU_JAVANETPKG "SocketException", "Accept failed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   475
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   476
            return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   477
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   478
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   479
        newfd = RDMA_Accept(fd, &sa.sa, &slen);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   480
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   481
        if (newfd >= 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   482
            SET_BLOCKING(newfd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   483
            break;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   484
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   485
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   486
        if (!(errno == ECONNABORTED || errno == EWOULDBLOCK)) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   487
            break;
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
        if (nanoTimeout >= NET_NSEC_PER_MSEC) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   491
            currNanoTime = JVM_NanoTime(env, 0);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   492
            nanoTimeout -= (currNanoTime - prevNanoTime);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   493
            if (nanoTimeout < NET_NSEC_PER_MSEC) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   494
                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   495
                        "Accept timed out");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   496
                return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   497
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   498
            prevNanoTime = currNanoTime;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   499
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   500
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   501
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   502
    if (newfd < 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   503
        if (newfd == -2) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   504
            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   505
                    "operation interrupted");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   506
        } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   507
            if (errno == EINVAL) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   508
                errno = EBADF;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   509
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   510
            if (errno == EBADF) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   511
                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   512
                        "Socket closed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   513
            } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   514
                JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   515
                        JNU_JAVANETPKG "SocketException", "Accept failed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   516
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   517
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   518
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   519
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   520
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   521
    socketAddressObj = NET_SockaddrToInetAddress(env, &sa, &port);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   522
    if (socketAddressObj == NULL) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   523
        rs_close(newfd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   524
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   525
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   526
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   527
    socketFdObj = (*env)->GetObjectField(env, socket, psi_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   528
    (*env)->SetIntField(env, socketFdObj, IO_fd_fdID, newfd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   529
    (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   530
    (*env)->SetIntField(env, socket, psi_portID, port);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   531
    port = (*env)->GetIntField(env, cls, psi_localportID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   532
    (*env)->SetIntField(env, socket, psi_localportID, port);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   533
}
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   534
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   535
JNIEXPORT void JNICALL
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   536
Java_jdk_internal_net_rdma_RdmaSocketImpl_rdmaSocketClose(JNIEnv *env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   537
        jclass cls) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   538
    jobject fdObj = (*env)->GetObjectField(env, cls, psi_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   539
    jint fd;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   540
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   541
    if (IS_NULL(fdObj)) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   542
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   543
                "socket already closed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   544
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   545
    } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   546
        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   547
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   548
    if (fd != -1) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   549
        (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   550
        RDMA_SocketClose(fd);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   551
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   552
}
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   553
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   554
JNIEXPORT void JNICALL
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   555
Java_jdk_internal_net_rdma_RdmaSocketImpl_rdmaSocketShutdown(JNIEnv *env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   556
        jclass cls, jint howto) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   557
    jobject fdObj = (*env)->GetObjectField(env, cls, psi_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   558
    jint fd;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   559
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   560
    if (IS_NULL(fdObj)) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   561
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   562
                "socket already closed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   563
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   564
    } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   565
        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   566
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   567
    rs_shutdown(fd, howto);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   568
}
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   569
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   570
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   571
JNIEXPORT void JNICALL
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   572
Java_jdk_internal_net_rdma_RdmaSocketImpl_rdmaSocketSetOption(JNIEnv *env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   573
        jclass cls, jint cmd, jboolean on, jobject value) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   574
    int fd;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   575
    int level, optname, optlen;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   576
    union {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   577
        int i;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   578
        struct linger ling;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   579
    } optval;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   580
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   581
    fd = getFD(env, cls);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   582
    if (fd < 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   583
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   584
                "Socket closed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   585
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   586
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   587
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   588
    if (cmd == java_net_SocketOptions_SO_TIMEOUT) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   589
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   590
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   591
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   592
    if (RDMA_MapSocketOption(cmd, &level, &optname)) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   593
        JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   594
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   595
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   596
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   597
    switch (cmd) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   598
        case java_net_SocketOptions_SO_SNDBUF :
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   599
        case java_net_SocketOptions_SO_RCVBUF :
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   600
            {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   601
                jclass cls;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   602
                jfieldID fid;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   603
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   604
                cls = (*env)->FindClass(env, "java/lang/Integer");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   605
                CHECK_NULL(cls);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   606
                fid = (*env)->GetFieldID(env, cls, "value", "I");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   607
                CHECK_NULL(fid);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   608
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   609
                optval.i = (*env)->GetIntField(env, value, fid);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   610
                optlen = sizeof(optval.i);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   611
                break;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   612
            }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   613
        default :
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   614
            optval.i = (on ? 1 : 0);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   615
            optlen = sizeof(optval.i);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   616
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   617
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   618
    if (RDMA_SetSockOpt(fd, level, optname, (const void *)&optval, optlen) < 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   619
        JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   620
                JNU_JAVANETPKG "SocketException", "Error setting socket option");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   621
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   622
}
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   623
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   624
JNIEXPORT jint JNICALL
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   625
Java_jdk_internal_net_rdma_RdmaSocketImpl_rdmaSocketGetOption(JNIEnv *env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   626
        jclass cls, jint cmd, jobject iaContainerObj) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   627
    int fd;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   628
    int level, optname, optlen;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   629
    union {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   630
        int i;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   631
        struct linger ling;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   632
    } optval;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   633
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   634
    fd = getFD(env, cls);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   635
    if (fd < 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   636
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   637
                "Socket closed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   638
        return -1;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   639
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   640
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   641
    if (cmd == java_net_SocketOptions_SO_BINDADDR) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   642
        SOCKETADDRESS sa;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   643
        socklen_t len = sizeof(SOCKETADDRESS);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   644
        int port;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   645
        jobject iaObj;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   646
        jclass iaCntrClass;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   647
        jfieldID iaFieldID;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   648
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   649
        if (rs_getsockname(fd, &sa.sa, &len) < 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   650
            JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   651
                    JNU_JAVANETPKG "SocketException",
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   652
                    "Error getting socket name");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   653
            return -1;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   654
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   655
        iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   656
        CHECK_NULL_RETURN(iaObj, -1);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   657
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   658
        iaCntrClass = (*env)->GetObjectClass(env, iaContainerObj);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   659
        iaFieldID = (*env)->GetFieldID(env, iaCntrClass,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   660
                "addr", "Ljava/net/InetAddress;");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   661
        CHECK_NULL_RETURN(iaFieldID, -1);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   662
        (*env)->SetObjectField(env, iaContainerObj, iaFieldID, iaObj);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   663
        return 0;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   664
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   665
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   666
    if (RDMA_MapSocketOption(cmd, &level, &optname)) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   667
        JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   668
        return -1;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   669
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   670
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   671
    optlen = sizeof(optval.i);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   672
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   673
    if (RDMA_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   674
        JNU_ThrowByNameWithMessageAndLastError(env,
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   675
        JNU_JAVANETPKG "SocketException", "Error getting socket option");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   676
        return -1;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   677
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   678
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   679
    switch (cmd) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   680
        case java_net_SocketOptions_SO_SNDBUF:
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   681
        case java_net_SocketOptions_SO_RCVBUF:
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   682
            return optval.i;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   683
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   684
        default :
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   685
            return (optval.i == 0) ? -1 : 1;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   686
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   687
}
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   688
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   689
JNIEXPORT void JNICALL
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   690
Java_jdk_internal_net_rdma_RdmaSocketImpl_rdmaSocketSendUrgentData(
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   691
        JNIEnv *env, jclass cls, jint data) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   692
    jobject fdObj = (*env)->GetObjectField(env, cls, psi_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   693
    int n, fd;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   694
    unsigned char d = data & 0xFF;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   695
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   696
    if (IS_NULL(fdObj)) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   697
        JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   698
        return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   699
    } else {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   700
        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   701
        if (fd == -1) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   702
            JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   703
            return;
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   704
        }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   705
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   706
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   707
    n = RDMA_Send(fd, (char *)&d, 1, MSG_OOB);
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   708
    if (n == -1) {
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   709
        JNU_ThrowIOExceptionWithLastError(env, "Write failed");
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   710
    }
512e7cc6ccce Initial load of JEP 337 implementation
alanb
parents:
diff changeset
   711
}