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