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

Print this page

        

@@ -23,23 +23,25 @@
  * questions.
  */
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <signal.h>
 #include <pthread.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/select.h>
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/uio.h>
 #include <unistd.h>
 #include <errno.h>
-
 #include <sys/poll.h>
 
+#include "jni_util.h"
+
 /*
  * Stack allocated by thread when doing blocking operation
  */
 typedef struct threadEntry {
     pthread_t thr;                      /* this thread */

@@ -337,13 +339,17 @@
 /*
  * Wrapper for select(s, timeout). We are using select() on Mac OS due to Bug 7131399.
  * Auto restarts with adjusted timeout if interrupted by
  * signal other than our wakeup signal.
  */
-int NET_Timeout(int s, long timeout) {
+int NET_Timeout(JNIEnv *env, int s, long timeout) {
     long prevtime = 0, newtime;
     struct timeval t, *tp = &t;
+    fd_set fds;
+    fd_set* fdsp = NULL;
+    int allocated = 0;
+    threadEntry_t self;
     fdEntry_t *fdEntry = getFdEntry(s);
 
     /*
      * Check that fd hasn't been closed.
      */

@@ -369,24 +375,34 @@
         /* Poll */
         t.tv_sec = 0;
         t.tv_usec = 0;
     }
 
+    if (s < FD_SETSIZE) {
+        fdsp = &fds;
+        FD_ZERO(fdsp);
+    } else {
+        int length = (howmany(s+1, NFDBITS)) * sizeof(int);        
+        fdsp = (fd_set *) calloc(1, length);
+        if (fdsp == NULL) {
+            JNU_ThrowOutOfMemoryError(env, "NET_Select native heap allocation failed");
+            return 0;
+        }
+        allocated = 1;
+    }
+    FD_SET(s, fdsp);
+
     for(;;) {
-        fd_set rfds;
         int rv;
-        threadEntry_t self;
 
         /*
          * call select on the fd. If interrupted by our wakeup signal
          * errno will be set to EBADF.
          */
-        FD_ZERO(&rfds);
-        FD_SET(s, &rfds);
 
         startOp(fdEntry, &self);
-        rv = select(s+1, &rfds, 0, 0, tp);
+        rv = select(s+1, fdsp, 0, 0, tp);
         endOp(fdEntry, &self);
 
         /*
          * If interrupted then adjust timeout. If timeout
          * has expired return 0 (indicating timeout expired).

@@ -396,17 +412,21 @@
                 struct timeval now;
                 gettimeofday(&now, NULL);
                 newtime = now.tv_sec * 1000  +  now.tv_usec / 1000;
                 timeout -= newtime - prevtime;
                 if (timeout <= 0) {
+                    if (allocated != 0)
+                        free(fdsp);
                     return 0;
                 }
                 prevtime = newtime;
                 t.tv_sec = timeout / 1000;
                 t.tv_usec = (timeout % 1000) * 1000;
             }
         } else {
+            if (allocated != 0)
+                free(fdsp);
             return rv;
         }
 
     }
 }