6483406: new ServerSocket() sometimes takes more than 3 minutes on Suse Linux
authorjccollet
Fri, 13 Jun 2008 17:43:50 +0200
changeset 710 57367409c4a5
parent 709 4d98e12330e6
child 711 b22e3837ba56
6483406: new ServerSocket() sometimes takes more than 3 minutes on Suse Linux Summary: Switch to socketpair() call to create marker fd Reviewed-by: alanb
jdk/src/solaris/native/java/net/PlainSocketImpl.c
--- a/jdk/src/solaris/native/java/net/PlainSocketImpl.c	Thu Jun 12 17:28:08 2008 +0100
+++ b/jdk/src/solaris/native/java/net/PlainSocketImpl.c	Fri Jun 13 17:43:50 2008 +0200
@@ -95,94 +95,24 @@
  */
 static int getMarkerFD()
 {
-    int server_fd, child_fd, connect_fd;
-    SOCKADDR him;
-    int type, len, port;
+    int sv[2];
 
-    type = AF_INET;
-#ifdef AF_INET6
-    if (ipv6_available()) {
-        type = AF_INET6;
+#ifdef AF_UNIX
+    if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
+        return -1;
     }
+#else
+    return -1;
 #endif
 
     /*
-     * Create listener on any port
-     */
-    server_fd = JVM_Socket(type, SOCK_STREAM, 0);
-    if (server_fd < 0) {
-        return -1;
-    }
-    if (JVM_Listen(server_fd, 1) == -1) {
-        JVM_SocketClose(server_fd);
-        return -1;
-    }
-    len = SOCKADDR_LEN;
-    if (JVM_GetSockName(server_fd, (struct sockaddr *)&him, &len) == -1) {
-        JVM_SocketClose(server_fd);
-        return -1;
-    }
-    port = NET_GetPortFromSockaddr((struct sockaddr *)&him);
-
-    /*
-     * Establish connection from client socket.
-     * Server is bound to 0.0.0.0/X or ::/X
-     * We connect to 127.0.0.1/X or ::1/X
-     */
-#ifdef AF_INET6
-    if (ipv6_available()) {
-        struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)&him;
-        jbyte caddr[16];
-        memset((char *) caddr, 0, 16);
-        caddr[15] = 1;
-        memset((char *)him6, 0, sizeof(struct sockaddr_in6));
-        memcpy((void *)&(him6->sin6_addr), caddr, sizeof(struct in6_addr) );
-        him6->sin6_port = htons((short) port);
-        him6->sin6_family = AF_INET6;
-        len = sizeof(struct sockaddr_in6) ;
-    } else
-#endif /* AF_INET6 */
-    {
-        struct sockaddr_in *him4 = (struct sockaddr_in*)&him;
-        memset((char *) him4, 0, sizeof(struct sockaddr_in));
-        him4->sin_port = htons((short) port);
-        him4->sin_addr.s_addr = (uint32_t) htonl(0x7f000001);
-        him4->sin_family = AF_INET;
-        len = sizeof(struct sockaddr_in);
-    }
-    connect_fd = JVM_Socket(type, SOCK_STREAM, 0);
-    if (connect_fd < 0) {
-        JVM_SocketClose(server_fd);
-        return -1;
-    }
-    if (JVM_Connect(connect_fd, (struct sockaddr *) &him, len) == -1) {
-        JVM_SocketClose(server_fd);
-        JVM_SocketClose(connect_fd);
-        return -1;
-    }
-
-    /*
-     * Server accepts connection - do in in non-blocking mode to avoid
-     * hanging if there's an error (should never happen!!!)
-     */
-    SET_NONBLOCKING(server_fd);
-    len = SOCKADDR_LEN;
-    child_fd = JVM_Accept(server_fd, (struct sockaddr *)&him, (jint *)&len);
-    if (child_fd == -1) {
-        JVM_SocketClose(server_fd);
-        JVM_SocketClose(connect_fd);
-        return -1;
-    }
-
-    /*
-     * Finally shutdown connect_fd (any reads to this fd will get
+     * Finally shutdown sv[0] (any reads to this fd will get
      * EOF; any writes will get an error).
      */
-    JVM_SocketShutdown(connect_fd, 2);
-    JVM_SocketClose(child_fd);
-    JVM_SocketClose(server_fd);
+    JVM_SocketShutdown(sv[0], 2);
+    JVM_SocketClose(sv[1]);
 
-    return connect_fd;
+    return sv[0];
 }
 
 
@@ -1087,7 +1017,7 @@
      */
     if (cmd == java_net_SocketOptions_SO_BINDADDR) {
         SOCKADDR him;
-        int len = 0;
+        socklen_t len = 0;
         int port;
         jobject iaObj;
         jclass iaCntrClass;