src/solaris/native/java/net/PlainDatagramSocketImpl.c

Print this page

        

@@ -81,48 +81,69 @@
 static jfieldID pdsi_multicastInterfaceID;
 static jfieldID pdsi_loopbackID;
 static jfieldID pdsi_ttlID;
 #endif
 
-/*
- * Returns a java.lang.Integer based on 'i'
- */
-static jobject createInteger(JNIEnv *env, int i) {
-    static jclass i_class;
-    static jmethodID i_ctrID;
+static jclass i_class;
+static jmethodID i_ctrID;
+static jfieldID i_valueID;
 
+int initIntegerIDs(JNIEnv* env) {
     if (i_class == NULL) {
         jclass c = (*env)->FindClass(env, "java/lang/Integer");
         CHECK_NULL_RETURN(c, NULL);
         i_ctrID = (*env)->GetMethodID(env, c, "<init>", "(I)V");
         CHECK_NULL_RETURN(i_ctrID, NULL);
+        i_valueID = (*env)->GetFieldID(env, c, "value", "I");
+        CHECK_NULL_RETURN(i_valueID, NULL);
         i_class = (*env)->NewGlobalRef(env, c);
         CHECK_NULL_RETURN(i_class, NULL);
     }
+    return 1;
+}
 
+/* Returns a java.lang.Integer based on 'i' */
+static jobject createInteger(JNIEnv *env, int i) {
+    CHECK_NULL_RETURN(initIntegerIDs(env), NULL);
     return ( (*env)->NewObject(env, i_class, i_ctrID, i) );
 }
 
-/*
- * Returns a java.lang.Boolean based on 'b'
- */
-static jobject createBoolean(JNIEnv *env, int b) {
-    static jclass b_class;
-    static jmethodID b_ctrID;
+/* Returns a jint based on the given java.lang.Integer */
+static jint retrieveInteger(JNIEnv *env, jobject i) {
+    CHECK_NULL_RETURN(initIntegerIDs(env), NULL);
+    return (*env)->GetIntField(env, i, i_valueID);
+}
 
+static jclass b_class;
+static jmethodID b_ctrID;
+static jfieldID b_valueID;
+
+int initBooleanIDs(JNIEnv* env) {
     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_valueID = (*env)->GetFieldID(env, c, "value", "Z");
+        CHECK_NULL_RETURN(b_valueID, NULL);
         b_class = (*env)->NewGlobalRef(env, c);
         CHECK_NULL_RETURN(b_class, NULL);
     }
+    return 1;
+}
 
+/* Returns a java.lang.Boolean based on 'b' */
+static jobject createBoolean(JNIEnv *env, int b) {
+    CHECK_NULL_RETURN(initBooleanIDs(env), NULL);
     return( (*env)->NewObject(env, b_class, b_ctrID, (jboolean)(b!=0)) );
 }
 
+/* Returns a jboolean based on the given java.lang.Boolean */
+static jboolean retrieveBoolean(JNIEnv *env, jobject b) {
+    CHECK_NULL_RETURN(initBooleanIDs(env), NULL);
+    return (*env)->GetBooleanField(env, b, b_valueID);
+}
 
 /*
  * Returns the fd for a PlainDatagramSocketImpl or -1
  * if closed.
  */

@@ -1133,30 +1154,16 @@
 /*
  * Set outgoing multicast interface designated by a NetworkInterface.
  * Throw exception if failed.
  */
 static void mcast_set_if_by_if_v4(JNIEnv *env, jobject this, int fd, jobject value) {
-    static jfieldID ni_addrsID;
-    static jfieldID ia_addressID;
     struct in_addr in;
     jobjectArray addrArray;
     jsize len;
     jobject addr;
     int i;
 
-    if (ni_addrsID == NULL) {
-        jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
-        CHECK_NULL(c);
-        ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
-                                        "[Ljava/net/InetAddress;");
-        CHECK_NULL(ni_addrsID);
-        c = (*env)->FindClass(env,"java/net/InetAddress");
-        CHECK_NULL(c);
-        ia_addressID = (*env)->GetFieldID(env, c, "address", "I");
-        CHECK_NULL(ia_addressID);
-    }
-
     addrArray = (*env)->GetObjectField(env, value, ni_addrsID);
     len = (*env)->GetArrayLength(env, addrArray);
 
     /*
      * Check that there is at least one address bound to this

@@ -1190,19 +1197,12 @@
  * Set outgoing multicast interface designated by a NetworkInterface.
  * Throw exception if failed.
  */
 #ifdef AF_INET6
 static void mcast_set_if_by_if_v6(JNIEnv *env, jobject this, int fd, jobject value) {
-    static jfieldID ni_indexID;
     int index;
 
-    if (ni_indexID == NULL) {
-        jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
-        CHECK_NULL(c);
-        ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
-        CHECK_NULL(ni_indexID);
-    }
     index = (*env)->GetIntField(env, value, ni_indexID);
 
     if (JVM_SetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
                        (const char*)&index, sizeof(index)) < 0) {
         if (errno == EINVAL && index > 0) {

@@ -1232,20 +1232,12 @@
 /*
  * Set outgoing multicast interface designated by an InetAddress.
  * Throw exception if failed.
  */
 static void mcast_set_if_by_addr_v4(JNIEnv *env, jobject this, int fd, jobject value) {
-    static jfieldID ia_addressID;
     struct in_addr in;
 
-    if (ia_addressID == NULL) {
-        jclass c = (*env)->FindClass(env,"java/net/InetAddress");
-        CHECK_NULL(c);
-        ia_addressID = (*env)->GetFieldID(env, c, "address", "I");
-        CHECK_NULL(ia_addressID);
-    }
-
     in.s_addr = htonl( (*env)->GetIntField(env, value, ia_addressID) );
 
     if (JVM_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_IF,
                        (const char*)&in, sizeof(in)) < 0) {
         NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",

@@ -1257,18 +1249,10 @@
  * Set outgoing multicast interface designated by an InetAddress.
  * Throw exception if failed.
  */
 #ifdef AF_INET6
 static void mcast_set_if_by_addr_v6(JNIEnv *env, jobject this, int fd, jobject value) {
-    static jclass ni_class;
-    if (ni_class == NULL) {
-        jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
-        CHECK_NULL(c);
-        ni_class = (*env)->NewGlobalRef(env, c);
-        CHECK_NULL(ni_class);
-    }
-
     value = Java_java_net_NetworkInterface_getByInetAddress0(env, ni_class, value);
     if (value == NULL) {
         if (!(*env)->ExceptionOccurred(env)) {
             JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                  "bad argument for IP_MULTICAST_IF"

@@ -1360,21 +1344,14 @@
 
 /*
  * Enable/disable local loopback of multicast datagrams.
  */
 static void mcast_set_loop_v4(JNIEnv *env, jobject this, int fd, jobject value) {
-    jclass cls;
-    jfieldID fid;
     jboolean on;
     char loopback;
 
-    cls = (*env)->FindClass(env, "java/lang/Boolean");
-    CHECK_NULL(cls);
-    fid =  (*env)->GetFieldID(env, cls, "value", "Z");
-    CHECK_NULL(fid);
-
-    on = (*env)->GetBooleanField(env, value, fid);
+    on = retrieveBoolean(env, value);
     loopback = (!on ? 1 : 0);
 
     if (NET_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&loopback, sizeof(char)) < 0) {
         NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
         return;

@@ -1384,21 +1361,14 @@
 /*
  * Enable/disable local loopback of multicast datagrams.
  */
 #ifdef AF_INET6
 static void mcast_set_loop_v6(JNIEnv *env, jobject this, int fd, jobject value) {
-    jclass cls;
-    jfieldID fid;
     jboolean on;
     int loopback;
 
-    cls = (*env)->FindClass(env, "java/lang/Boolean");
-    CHECK_NULL(cls);
-    fid =  (*env)->GetFieldID(env, cls, "value", "Z");
-    CHECK_NULL(fid);
-
-    on = (*env)->GetBooleanField(env, value, fid);
+    on = retrieveBoolean(env, value);
     loopback = (!on ? 1 : 0);
 
     if (NET_SetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&loopback, sizeof(int)) < 0) {
         NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
         return;

@@ -1505,37 +1475,20 @@
     switch (opt) {
         case java_net_SocketOptions_SO_SNDBUF :
         case java_net_SocketOptions_SO_RCVBUF :
         case java_net_SocketOptions_IP_TOS :
             {
-                jclass cls;
-                jfieldID fid;
-
-                cls = (*env)->FindClass(env, "java/lang/Integer");
-                CHECK_NULL(cls);
-                fid =  (*env)->GetFieldID(env, cls, "value", "I");
-                CHECK_NULL(fid);
-
-                optval.i = (*env)->GetIntField(env, value, fid);
+                optval.i = retrieveInteger(env, value);
                 optlen = sizeof(optval.i);
                 break;
             }
 
         case java_net_SocketOptions_SO_REUSEADDR:
         case java_net_SocketOptions_SO_BROADCAST:
             {
-                jclass cls;
-                jfieldID fid;
-                jboolean on;
+                jboolean on = retrieveBoolean(env, value);
 
-                cls = (*env)->FindClass(env, "java/lang/Boolean");
-                CHECK_NULL(cls);
-                fid =  (*env)->GetFieldID(env, cls, "value", "Z");
-                CHECK_NULL(fid);
-
-                on = (*env)->GetBooleanField(env, value, fid);
-
                 /* SO_REUSEADDR or SO_BROADCAST */
                 optval.i = (on ? 1 : 0);
                 optlen = sizeof(optval.i);
 
                 break;

@@ -1591,19 +1544,10 @@
 
     /*
      * IPv4 implementation
      */
     if (isIPV4) {
-        static jclass inet4_class;
-        static jmethodID inet4_ctrID;
-        static jfieldID inet4_addrID;
-
-        static jclass ni_class;
-        static jmethodID ni_ctrID;
-        static jfieldID ni_indexID;
-        static jfieldID ni_addrsID;
-
         jobjectArray addrArray;
         jobject addr;
         jobject ni;
 
         struct in_addr in;

@@ -1626,28 +1570,18 @@
         }
 
         /*
          * Construct and populate an Inet4Address
          */
-        if (inet4_class == NULL) {
-            jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
-            CHECK_NULL_RETURN(c, NULL);
-            inet4_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
-            CHECK_NULL_RETURN(inet4_ctrID, NULL);
-            inet4_addrID = (*env)->GetFieldID(env, c, "address", "I");
-            CHECK_NULL_RETURN(inet4_addrID, NULL);
-            inet4_class = (*env)->NewGlobalRef(env, c);
-            CHECK_NULL_RETURN(inet4_class, NULL);
-        }
-        addr = (*env)->NewObject(env, inet4_class, inet4_ctrID, 0);
+        addr = (*env)->NewObject(env, ia4_class, ia4_ctrID, 0);
         CHECK_NULL_RETURN(addr, NULL);
 
 #ifdef __linux__
-        (*env)->SetIntField(env, addr, inet4_addrID,
+        (*env)->SetIntField(env, addr, ia_addressID,
                 (isOldKernel ? ntohl(mreqn.imr_address.s_addr) : ntohl(in.s_addr)) );
 #else
-        (*env)->SetIntField(env, addr, inet4_addrID, ntohl(in.s_addr));
+        (*env)->SetIntField(env, addr, ia_addressID, ntohl(in.s_addr));
 #endif
 
         /*
          * For IP_MULTICAST_IF return InetAddress
          */

@@ -1657,23 +1591,10 @@
 
         /*
          * For IP_MULTICAST_IF2 we get the NetworkInterface for
          * this address and return it
          */
-        if (ni_class == NULL) {
-            jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
-            CHECK_NULL_RETURN(c, NULL);
-            ni_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
-            CHECK_NULL_RETURN(ni_ctrID, NULL);
-            ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
-            CHECK_NULL_RETURN(ni_indexID, NULL);
-            ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
-                                            "[Ljava/net/InetAddress;");
-            CHECK_NULL_RETURN(ni_addrsID, NULL);
-            ni_class = (*env)->NewGlobalRef(env, c);
-            CHECK_NULL_RETURN(ni_class, NULL);
-        }
         ni = Java_java_net_NetworkInterface_getByInetAddress0(env, ni_class, addr);
         if (ni) {
             return ni;
         }
 

@@ -1684,11 +1605,11 @@
          */
         ni = (*env)->NewObject(env, ni_class, ni_ctrID, 0);
         CHECK_NULL_RETURN(ni, NULL);
 
         (*env)->SetIntField(env, ni, ni_indexID, -1);
-        addrArray = (*env)->NewObjectArray(env, 1, inet4_class, NULL);
+        addrArray = (*env)->NewObjectArray(env, 1, ia4_class, NULL);
         CHECK_NULL_RETURN(addrArray, NULL);
         (*env)->SetObjectArrayElement(env, addrArray, 0, addr);
         (*env)->SetObjectField(env, ni, ni_addrsID, addrArray);
         return ni;
     }

@@ -1698,16 +1619,10 @@
     /*
      * IPv6 implementation
      */
     if ((opt == java_net_SocketOptions_IP_MULTICAST_IF) ||
         (opt == java_net_SocketOptions_IP_MULTICAST_IF2)) {
-
-        static jclass ni_class;
-        static jmethodID ni_ctrID;
-        static jfieldID ni_indexID;
-        static jfieldID ni_addrsID;
-        static jclass ia_class;
         static jmethodID ia_anyLocalAddressID;
 
         int index;
         int len = sizeof(index);
 

@@ -1731,32 +1646,16 @@
                                "Error getting socket option");
                 return NULL;
             }
         }
 
-        if (ni_class == NULL) {
-            jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
-            CHECK_NULL_RETURN(c, NULL);
-            ni_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
-            CHECK_NULL_RETURN(ni_ctrID, NULL);
-            ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
-            CHECK_NULL_RETURN(ni_indexID, NULL);
-            ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
-                                            "[Ljava/net/InetAddress;");
-            CHECK_NULL_RETURN(ni_addrsID, NULL);
-
-            ia_class = (*env)->FindClass(env, "java/net/InetAddress");
-            CHECK_NULL_RETURN(ia_class, NULL);
-            ia_class = (*env)->NewGlobalRef(env, ia_class);
-            CHECK_NULL_RETURN(ia_class, NULL);
+        if (ia_anyLocalAddressID == NULL) {
             ia_anyLocalAddressID = (*env)->GetStaticMethodID(env,
                                                              ia_class,
                                                              "anyLocalAddress",
                                                              "()Ljava/net/InetAddress;");
             CHECK_NULL_RETURN(ia_anyLocalAddressID, NULL);
-            ni_class = (*env)->NewGlobalRef(env, c);
-            CHECK_NULL_RETURN(ni_class, NULL);
         }
 
         /*
          * If multicast to a specific interface then return the
          * interface (for IF2) or the any address on that interface

@@ -2166,19 +2065,10 @@
          *              NetworkInterface
          */
         if (niObj != NULL) {
 #if defined(__linux__) && defined(AF_INET6)
             if (ipv6_available()) {
-                static jfieldID ni_indexID;
-
-                if (ni_indexID == NULL) {
-                    jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
-                    CHECK_NULL(c);
-                    ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
-                    CHECK_NULL(ni_indexID);
-                }
-
                 mname.imr_multiaddr.s_addr = htonl((*env)->GetIntField(env, iaObj, ia_addressID));
                 mname.imr_address.s_addr = 0;
                 mname.imr_ifindex =  (*env)->GetIntField(env, niObj, ni_indexID);
                 mname_len = sizeof(struct ip_mreqn);
             } else