< prev index next >

src/java.base/unix/native/libnet/ExtendedOptionsImpl.c

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 52,61 **** --- 52,62 ---- static void setStatus(JNIEnv *env, jobject obj, int errval); /* OS specific code is implemented in these three functions */ static jboolean flowSupported0() ; + static jboolean quickack_available(); /* * Class: sun_net_ExtendedOptionsImpl * Method: init * Signature: ()V
*** 140,149 **** --- 141,169 ---- CHECK_NULL_RETURN(f, NULL); return f; } /* + * Returns a java.lang.Boolean based on 'b' + */ + static jobject createBoolean(JNIEnv *env, int b) { + static jclass b_class; + static jmethodID b_ctrID; + + if (b_class == NULL) { + jclass c = (*env)->FindClass(env, "java/lang/Boolean"); + CHECK_NULL_RETURN(c, NULL); + b_ctrID = (*env)->GetMethodID(env, c, "<init>", "(Z)V"); + CHECK_NULL_RETURN(b_ctrID, NULL); + b_class = (*env)->NewGlobalRef(env, c); + CHECK_NULL_RETURN(b_class, NULL); + } + + return ((*env)->NewObject(env, b_class, b_ctrID, (jboolean) (b != 0))); + } + + /* * Retrieve the int file-descriptor from a public socket type object. * Gets impl, then the FileDescriptor from the impl, and then the fd * from that. */ static int getFD(JNIEnv *env, jobject fileDesc) {
*** 335,344 **** --- 355,476 ---- return JNI_FALSE; } #endif /* __solaris__ */ + #ifdef __linux__ + + /* + * Class: sun_net_ExtendedOptionsImpl + * Method: setQuickAckOption + * Signature: (Ljava/io/FileDescriptor;Ljava/lang/Object;)V + */ + JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setQuickAckOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc, jboolean on) { + int fd = getFD(env, fileDesc); + int optval; + if (fd < 0) { + NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed"); + } else { + int rv; + optval = (on ? 1 : 0); + rv = setsockopt(fd, SOL_SOCKET, SO_QUICKACK, &optval, sizeof (optval)); + if (rv < 0) { + if (errno == ENOPROTOOPT) { + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); + } else { + NET_ERROR(env, JNU_JAVANETPKG "SocketException", + "set option SO_REUSEPORT failed"); + } + } + } + } + + /* + * Class: sun_net_ExtendedOptionsImpl + * Method: getQuickAckOption + * Signature: (Ljava/io/FileDescriptor;)Ljava/lang/Object; + */ + JNIEXPORT jobject JNICALL Java_sun_net_ExtendedOptionsImpl_getQuickAckOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc) + { + int fd = getFD(env, fileDesc); + if (fd < 0) { + NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed"); + return JNI_FALSE; + } else { + int on; + socklen_t sz = sizeof(on); + int rv = getsockopt(fd, SOL_SOCKET, SO_QUICKACK, &on, &sz); + if (rv < 0) { + if (errno == ENOPROTOOPT) { + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); + } else { + NET_ERROR(env, JNU_JAVANETPKG "SocketException", + "setoption SO_QUICKACK failed"); + } + } + return createBoolean(env, on); + } + } + + static jboolean isQuickAckAvailable; + static jboolean isQuickAckAvailableChecked = JNI_FALSE; + static jboolean quickack_available() { + int one = 1; + int rv, s; + if (isQuickAckAvailableChecked) { + return isQuickAckAvailable; + } + s = socket(PF_INET, SOCK_STREAM, 0); + if (s < 0) { + isQuickAckAvailable = JNI_FALSE; + isQuickAckAvailableChecked = JNI_TRUE; + return JNI_FALSE; + } + rv = setsockopt(s, SOL_SOCKET, SO_QUICKACK, (void *) &one, sizeof (one)); + isQuickAckAvailableChecked = JNI_TRUE; + if (rv != 0 && errno == ENOPROTOOPT) { + isQuickAckAvailable = JNI_FALSE; + } else { + isQuickAckAvailable = JNI_TRUE; + } + close(s); + return isQuickAckAvailable; + } + + #else + + JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setQuickAckOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc, jboolean on) + { + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); + } + + JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_getQuickAckOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc) + { + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); + return JNI_FALSE; + } + + static jboolean quickack_available() { + return JNI_FALSE; + } + + #endif /* __linux__ */ + JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_flowSupported (JNIEnv *env, jclass UNUSED) { return flowSupported0(); } + + JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_isQuickAckAvailable0 + (JNIEnv *env, jclass UNUSED) + { + return quickack_available(); + }
< prev index next >