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;
}
}
}