calls to select(2) ignore exceptions
Archie Cobbs
archie at whistle.com
Mon Aug 17 19:17:42 PDT 1998
In the course of trying to track down an unrelated bug, I noticed that
when calling select(2), kaffe is ignoring any "exceptional conditions".
This seems like a bad thing to do. It should throw an IOException if
there are any exceptions on a file descriptor.
Here's a fairly simple patch which I think fixes this.. not sure
however. Would someone who's more familiar with these files give
a look?
Thanks,
-Archie
___________________________________________________________________________
Archie Cobbs * Whistle Communications, Inc. * http://www.whistle.com
Index: kaffe/kaffevm/systems/unix-internal/internal.c
===================================================================
RCS file: /cvs/mod/net/kaffe/kaffe/kaffevm/systems/unix-internal/internal.c,v
retrieving revision 1.1.1.1.4.1
diff -c -u -r1.1.1.1.4.1 internal.c
--- internal.c 1998/07/17 17:47:34 1.1.1.1.4.1
+++ internal.c 1998/08/18 02:16:09
@@ -451,6 +451,7 @@
int r;
fd_set rd;
fd_set wr;
+ fd_set ex;
Hjava_lang_Thread* tid;
Hjava_lang_Thread* ntid;
int i;
@@ -461,6 +462,14 @@
FD_COPY(&readsPending, &rd);
FD_COPY(&writesPending, &wr);
+ /* Take the logical OR of all readable and writable file descriptors
+ * to get the exception check set.
+ */
+ for (i = 0; i < sizeof(fd_set); i++) {
+ ((unsigned char *) &ex)[i] =
+ ((unsigned char *) &rd)[i] | ((unsigned char *) &wr)[i];
+ }
+
/*
* Select() is called with indefinite wait, but we have to make sure
* we can get interrupted by timer events. However, we should *NOT*
@@ -469,7 +478,7 @@
needReschedule = false;
b = blockInts;
blockInts = 0;
- r = (*Kaffe_SystemCallInterface._select)(maxFd+1, &rd, &wr, 0, 0);
+ r = (*Kaffe_SystemCallInterface._select)(maxFd+1, &rd, &wr, &ex, 0);
blockInts = b;
/* If select get's interrupted, just return now */
@@ -508,7 +517,7 @@
DBG( printf("Select returns %d\n", r); )
for (i = 0; r > 0 && i <= maxFd; i++) {
- if (readQ[i] != 0 && FD_ISSET(i, &rd)) {
+ if (readQ[i] != 0 && (FD_ISSET(i, &rd) || FD_ISSET(i, &ex))) {
for (tid = readQ[i]; tid != 0; tid = ntid) {
ntid = TCTX(tid)->nextQ;
resumeThread(tid);
@@ -516,7 +525,7 @@
readQ[i] = 0;
r--;
}
- if (writeQ[i] != 0 && FD_ISSET(i, &wr)) {
+ if (writeQ[i] != 0 && (FD_ISSET(i, &wr) || FD_ISSET(i, &ex))) {
for (tid = writeQ[i]; tid != 0; tid = ntid) {
ntid = TCTX(tid)->nextQ;
resumeThread(tid);
@@ -554,14 +563,14 @@
*/
FD_ZERO(&fset);
FD_SET(fd, &fset);
- r = (*Kaffe_SystemCallInterface._select)(fd+1, (op == TH_READ ? &fset : 0), (op == TH_WRITE ? &fset : 0), 0, &zerotimeout);
+ r = (*Kaffe_SystemCallInterface._select)(fd+1, (op == TH_READ ? &fset : 0), (op == TH_WRITE ? &fset : 0), &fset, &zerotimeout);
/* Select got interrupted - do it again */
if (r < 0 && errno == EINTR) {
goto retry;
}
/* If r != 0 then either its and error and we should return it, or the
- * file is okay to use so we should use it. Either way, return now.
+ * file is ready to use so we should use it. Either way, return now.
*/
if (r != 0) {
Tspinoff(0);
Index: kaffe/kaffevm/systems/unix-jthreads/jthread.c
===================================================================
RCS file: /cvs/mod/net/kaffe/kaffe/kaffevm/systems/unix-jthreads/jthread.c,v
retrieving revision 1.1.1.2.2.3
diff -c -u -r1.1.1.2.2.3 jthread.c
--- jthread.c 1998/08/07 17:41:27 1.1.1.2.2.3
+++ jthread.c 1998/08/18 02:16:09
@@ -1254,7 +1254,6 @@
/*
* Process incoming SIGIO
- * return 1 if select was interrupted
*/
static
void
@@ -1263,6 +1262,7 @@
int r;
fd_set rd;
fd_set wr;
+ fd_set ex;
jthread* tid;
jthread* ntid;
struct timeval zero = { 0, 0 };
@@ -1276,6 +1276,14 @@
FD_COPY(&readsPending, &rd);
FD_COPY(&writesPending, &wr);
+ /* Take the logical OR of all readable and writable file descriptors
+ * to get the exception check set.
+ */
+ for (i = 0; i < sizeof(fd_set); i++) {
+ ((unsigned char *) &ex)[i] =
+ ((unsigned char *) &rd)[i] | ((unsigned char *) &wr)[i];
+ }
+
/*
* figure out which fds are ready
*/
@@ -1284,7 +1292,7 @@
b = blockInts;
blockInts = 0;
}
- r = select(maxFd+1, &rd, &wr, 0, sleep ? 0 : &zero);
+ r = select(maxFd+1, &rd, &wr, &ex, sleep ? 0 : &zero);
if (sleep) {
blockInts = b;
if (sigPending)
@@ -1300,7 +1308,7 @@
dprintf("Select returns %d\n", r); )
for (i = 0; r > 0 && i <= maxFd; i++) {
- if (readQ[i] != 0 && FD_ISSET(i, &rd)) {
+ if (readQ[i] != 0 && (FD_ISSET(i, &rd) || FD_ISSET(i, &ex))) {
needReschedule = true;
for (tid = readQ[i]; tid != 0; tid = ntid) {
ntid = tid->nextQ;
@@ -1310,7 +1318,7 @@
readQ[i] = 0;
r--;
}
- if (writeQ[i] != 0 && FD_ISSET(i, &wr)) {
+ if (writeQ[i] != 0 && (FD_ISSET(i, &wr) || FD_ISSET(i, &ex))) {
needReschedule = true;
for (tid = writeQ[i]; tid != 0; tid = ntid) {
ntid = tid->nextQ;
More information about the kaffe
mailing list