--- a/UnixOperatingSystem.st Tue Jul 15 14:19:45 2003 +0200
+++ b/UnixOperatingSystem.st Tue Jul 15 16:03:28 2003 +0200
@@ -9050,25 +9050,32 @@
!
selectOnAnyReadable:readFdArray writable:writeFdArray exception:exceptFdArray
- into:resultFdArray withTimeOut:millis
- "wait for any fd in readFdArray (an Array of integers) to become ready for
- reading, writeFdArray to become ready for writing, or exceptFdArray to
- arrive exceptional data (i.e. out-of-band data).
- Timeout after t milliseconds or, if the timeout time is 0, immediately..
+ readableInto:readableResultFdArray writableInto:writableResultFdArray
+ exceptionInto:exceptionResultFdArray
+ withTimeOut:millis
+
+ "wait for any fd in readFdArray (an Array of integers) to become ready for reading,
+ writeFdArray to become ready for writing,
+ or exceptFdArray to arrive exceptional data (i.e. out-of-band data).
+ Timeout after t milliseconds or - if the timeout time is 0 - immediately..
Empty fd-sets will always wait. Zero time can be used to poll file-
descriptors (i.e. to check if I/O possible without blocking).
- The filedescriptors which are ready are returned in resultArray.
-
- Return the number of selected filedescriptors"
+ The corresponding filedescriptors which are ready are returned in readableResultFdArray,
+ writableResultFdArray and exceptionResultFdArray respectively.
+
+ Return the (overall) number of selected filedescriptors.
+ readableResultFdArray, writableResultFdArray and exceptionResultFdArray will
+ get a nil-value stored into the slot after the last valid fileDescriptor;
+ Thus, the caller can simply scan these arrays upTo the end or a nil value."
%{
fd_set rset, wset, eset;
struct timeval wt, et;
- int f, maxF, i, lX, bX;
+ int maxF;
INT t;
- OBJ fd, retFd;
int ret;
- int count, resultCount;
+ int cntR = 0, cntW = 0, cntE = 0;
+ int resultSizeReadable = 0, resultSizeWritable = 0, resultSizeException = 0;
int numFds = 0;
#ifndef __isArrayLike
# define __isArrayLike __isArray
@@ -9077,10 +9084,25 @@
if (!__isSmallInteger(millis)) {
goto fail;
}
- if (! __isArrayLike(resultFdArray)) {
- goto fail;
- }
- resultCount = __arraySize(resultFdArray);
+
+ if (readableResultFdArray != nil) {
+ if (! __isArrayLike(readableResultFdArray)) {
+ goto fail;
+ }
+ resultSizeReadable = __arraySize(readableResultFdArray);
+ }
+ if (writableResultFdArray != nil) {
+ if (! __isArrayLike(writableResultFdArray)) {
+ goto fail;
+ }
+ resultSizeWritable = __arraySize(writableResultFdArray);
+ }
+ if (exceptionResultFdArray != nil) {
+ if (! __isArrayLike(exceptionResultFdArray)) {
+ goto fail;
+ }
+ resultSizeException = __arraySize(exceptionResultFdArray);
+ }
FD_ZERO(&rset);
FD_ZERO(&wset);
@@ -9088,12 +9110,16 @@
maxF = -1;
if (__isNonNilObject(readFdArray)) {
+ int i, count;
+
if (! __isArrayLike(readFdArray)) {
goto fail;
}
count = __arraySize(readFdArray);
for (i=0; i<count;i++) {
+ OBJ fd;
+
fd = __ArrayInstPtr(readFdArray)->a_element[i];
if (fd != nil) {
if (! __isSmallInteger(fd)) {
@@ -9101,6 +9127,8 @@
fprintf(stderr, "[OS] warning: funny read-fd (0x%x) given to select\n", fd);
}
} else {
+ int f;
+
f = __intVal(fd);
if ((unsigned)f < FD_SETSIZE) {
FD_SET(f, &rset);
@@ -9117,11 +9145,15 @@
}
if (__isNonNilObject(writeFdArray)) {
+ int i, count;
+
if (! __isArrayLike(writeFdArray)) {
goto fail;
}
count = __arraySize(writeFdArray);
for (i=0; i<count;i++) {
+ OBJ fd;
+
fd = __ArrayInstPtr(writeFdArray)->a_element[i];
if (fd != nil) {
if (! __isSmallInteger(fd)) {
@@ -9129,6 +9161,8 @@
fprintf(stderr, "[OS] warning: funny write-fd (0x%x) given to select\n", fd);
}
} else {
+ int f;
+
f = __intVal(fd);
if ((unsigned)f < FD_SETSIZE) {
FD_SET(f, &wset);
@@ -9145,11 +9179,15 @@
}
if (__isNonNilObject(exceptFdArray)) {
+ int i, count;
+
if (! __isArrayLike(exceptFdArray)) {
goto fail;
}
count = __arraySize(exceptFdArray);
for (i=0; i<count;i++) {
+ OBJ fd;
+
fd = __ArrayInstPtr(exceptFdArray)->a_element[i];
if (fd != nil) {
if (! __isSmallInteger(fd)) {
@@ -9157,6 +9195,8 @@
fprintf(stderr, "[OS] warning: funny except-fd (0x%x) given to select\n", fd);
}
} else {
+ int f;
+
f = __intVal(fd);
if ((unsigned)f < FD_SETSIZE) {
FD_SET(f, &eset);
@@ -9208,20 +9248,45 @@
__END_INTERRUPTABLE__
if (ret > 0) {
- int cnt = 0;
- OBJ *__result = __arrayVal(resultFdArray);
+ OBJ *__resultR = __arrayVal(readableResultFdArray);
+ OBJ *__resultW = __arrayVal(writableResultFdArray);
+ OBJ *__resultE = __arrayVal(exceptionResultFdArray);
+ int i;
for (i=0; i <= maxF; i++) {
- if (FD_ISSET(i, &rset)
- || FD_ISSET(i, &wset)
- || FD_ISSET(i, &eset)) {
- if (cnt < resultCount) {
- __result[cnt] = __MKSMALLINT(i);
+ if (FD_ISSET(i, &rset)) {
+ if (cntR < resultSizeReadable) {
+ __resultR[cntR] = __MKSMALLINT(i);
}
- cnt++;
+ cntR++;
+ }
+
+ if (FD_ISSET(i, &wset)) {
+ if (cntW < resultSizeWritable) {
+ __resultW[cntW] = __MKSMALLINT(i);
+ }
+ cntW++;
+ }
+
+ if (FD_ISSET(i, &eset)) {
+ if (cntE < resultSizeException) {
+ __resultE[cntE] = __MKSMALLINT(i);
+ }
+ cntE++;
}
}
- RETURN (__MKSMALLINT(cnt));
+ /* add a delimiter */
+ if (cntR < resultSizeReadable) {
+ __resultR[cntR] = nil;
+ }
+ if (cntW < resultSizeWritable) {
+ __resultW[cntW] = nil;
+ }
+ if (cntE < resultSizeException) {
+ __resultE[cntE] = nil;
+ }
+
+ RETURN (__MKSMALLINT(cntR+cntW+cntE));
} else {
if (ret < 0) {
if (errno == EINTR) {
@@ -9242,8 +9307,6 @@
* Return 0 (no filedescriptor ready)
*/
RETURN (__MKSMALLINT(0));
-
-
fail: ;
%}.
"
@@ -9255,13 +9318,13 @@
!
selectOnAnyReadable:readFdArray writable:writeFdArray exception:exceptFdArray withTimeOut:millis
- "wait for any fd in readFdArray (an Array of integers) to become ready for
- reading, writeFdArray to become ready for writing, or exceptFdArray to
- arrive exceptional data (i.e. out-of-band data).
+ "wait for any fd in readFdArray (an Array of integers) to become ready for reading,
+ writeFdArray to become ready for writing,
+ or exceptFdArray to arrive exceptional data (i.e. out-of-band data).
Timeout after t milliseconds or, if the timeout time is 0, immediately..
Empty fd-sets will always wait. Zero time can be used to poll file-
descriptors (i.e. to check if I/O possible without blocking).
- Return first ready fd if I/O ok, nil if timed-out or interrupted."
+ Return the first ready fd if I/O ok, nil if timed-out or interrupted."
%{
fd_set rset, wset, eset;
@@ -9277,159 +9340,159 @@
#endif
if (__isSmallInteger(millis)) {
- FD_ZERO(&rset);
- FD_ZERO(&wset);
- FD_ZERO(&eset);
-
- maxF = -1;
- if (__isNonNilObject(readFdArray)) {
- if (! __isArrayLike(readFdArray)) {
- goto fail;
- }
- count = __arraySize(readFdArray);
-
- for (i=0; i<count;i++) {
- fd = __ArrayInstPtr(readFdArray)->a_element[i];
- if (fd != nil) {
- if (! __isSmallInteger(fd)) {
- if (@global(InfoPrinting) == true) {
- fprintf(stderr, "[OS] warning: funny read-fd (0x%x) given to select\n", fd);
- }
- } else {
- f = __intVal(fd);
- if ((unsigned)f < FD_SETSIZE) {
- FD_SET(f, &rset);
- if (f > maxF) maxF = f;
- numFds++;
- } else {
- if (@global(InfoPrinting) == true) {
- fprintf(stderr, "[OS] warning: huge read-fd (0x%x) given to select\n", fd);
- }
- }
- }
- }
- }
- }
-
- if (__isNonNilObject(writeFdArray)) {
- if (! __isArrayLike(writeFdArray)) {
- goto fail;
- }
- count = __arraySize(writeFdArray);
- for (i=0; i<count;i++) {
- fd = __ArrayInstPtr(writeFdArray)->a_element[i];
- if (fd != nil) {
- if (! __isSmallInteger(fd)) {
- if (@global(InfoPrinting) == true) {
- fprintf(stderr, "[OS] warning: funny write-fd (0x%x) given to select\n", fd);
- }
- } else {
- f = __intVal(fd);
- if ((unsigned)f < FD_SETSIZE) {
- FD_SET(f, &wset);
- if (f > maxF) maxF = f;
- numFds++;
- } else {
- if (@global(InfoPrinting) == true) {
- fprintf(stderr, "[OS] warning: huge write-fd (0x%x) given to select\n", fd);
- }
- }
- }
- }
- }
- }
-
- if (__isNonNilObject(exceptFdArray)) {
- if (! __isArrayLike(exceptFdArray)) {
- goto fail;
- }
- count = __arraySize(exceptFdArray);
- for (i=0; i<count;i++) {
- fd = __ArrayInstPtr(exceptFdArray)->a_element[i];
- if (fd != nil) {
- if (! __isSmallInteger(fd)) {
- if (@global(InfoPrinting) == true) {
- fprintf(stderr, "[OS] warning: funny except-fd (0x%x) given to select\n", fd);
- }
- } else {
- f = __intVal(fd);
- if ((unsigned)f < FD_SETSIZE) {
- FD_SET(f, &eset);
- if (f > maxF) maxF = f;
- numFds++;
- } else {
- if (@global(InfoPrinting) == true) {
- fprintf(stderr, "[OS] warning: huge except-fd (0x%x) given to select\n", fd);
- }
- }
- }
- }
- }
- }
-
- t = __intVal(millis);
- if (t) {
- wt.tv_sec = t / 1000;
- wt.tv_usec = (t % 1000) * 1000;
- } else {
- wt.tv_sec = wt.tv_usec = 0;
- }
-
- /*
- * make certain, that interrupt gets us out of the select
- * However, we must then care for moved objects.
- */
- __BEGIN_INTERRUPTABLE__
- errno = 0;
-
- if (t == 0) {
- /*
- * if there is no timeout time, we can stay here interruptable.
- */
- do {
- ret = select(maxF+1, &rset, &wset, &eset, &wt);
- } while ((ret < 0) && (errno == EINTR));
- } else {
- do {
- ret = select(maxF+1, &rset, &wset, &eset, &wt);
- /*
- * for now: dont loop; if we did, we had to adjust the vt-timeval;
- * could otherwise stay in this loop forever ...
- * Premature ret (before the time expired) must be handled by the caller.
- * A good solution is to update the wt-timeval and redo the select.
- */
- } while (0 /* (ret < 0) && (errno == EINTR) */ );
- }
- __END_INTERRUPTABLE__
-
- if (ret > 0) {
- for (i=0; i <= maxF; i++) {
- if (FD_ISSET(i, &rset)
- || FD_ISSET(i, &wset)
- || FD_ISSET(i, &eset)) {
- RETURN ( __MKSMALLINT(i) );
- }
- }
- } else {
- if (ret < 0) {
- if (errno == EINTR) {
- errno = 0;
- @global(LastErrorNumber) = nil;
- } else {
- if (@global(InfoPrinting) == true) {
- fprintf(stderr, "OS [info]: select errno = %d\n", errno);
- }
- @global(LastErrorNumber) = __MKSMALLINT(errno);
- }
- } else {
- @global(LastErrorNumber) = nil;
- }
- }
-
- /*
- * Return nil (means time expired or interrupted)
- */
- RETURN ( nil );
+ FD_ZERO(&rset);
+ FD_ZERO(&wset);
+ FD_ZERO(&eset);
+
+ maxF = -1;
+ if (__isNonNilObject(readFdArray)) {
+ if (! __isArrayLike(readFdArray)) {
+ goto fail;
+ }
+ count = __arraySize(readFdArray);
+
+ for (i=0; i<count;i++) {
+ fd = __ArrayInstPtr(readFdArray)->a_element[i];
+ if (fd != nil) {
+ if (! __isSmallInteger(fd)) {
+ if (@global(InfoPrinting) == true) {
+ fprintf(stderr, "[OS] warning: funny read-fd (0x%x) given to select\n", fd);
+ }
+ } else {
+ f = __intVal(fd);
+ if ((unsigned)f < FD_SETSIZE) {
+ FD_SET(f, &rset);
+ if (f > maxF) maxF = f;
+ numFds++;
+ } else {
+ if (@global(InfoPrinting) == true) {
+ fprintf(stderr, "[OS] warning: huge read-fd (0x%x) given to select\n", fd);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (__isNonNilObject(writeFdArray)) {
+ if (! __isArrayLike(writeFdArray)) {
+ goto fail;
+ }
+ count = __arraySize(writeFdArray);
+ for (i=0; i<count;i++) {
+ fd = __ArrayInstPtr(writeFdArray)->a_element[i];
+ if (fd != nil) {
+ if (! __isSmallInteger(fd)) {
+ if (@global(InfoPrinting) == true) {
+ fprintf(stderr, "[OS] warning: funny write-fd (0x%x) given to select\n", fd);
+ }
+ } else {
+ f = __intVal(fd);
+ if ((unsigned)f < FD_SETSIZE) {
+ FD_SET(f, &wset);
+ if (f > maxF) maxF = f;
+ numFds++;
+ } else {
+ if (@global(InfoPrinting) == true) {
+ fprintf(stderr, "[OS] warning: huge write-fd (0x%x) given to select\n", fd);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (__isNonNilObject(exceptFdArray)) {
+ if (! __isArrayLike(exceptFdArray)) {
+ goto fail;
+ }
+ count = __arraySize(exceptFdArray);
+ for (i=0; i<count;i++) {
+ fd = __ArrayInstPtr(exceptFdArray)->a_element[i];
+ if (fd != nil) {
+ if (! __isSmallInteger(fd)) {
+ if (@global(InfoPrinting) == true) {
+ fprintf(stderr, "[OS] warning: funny except-fd (0x%x) given to select\n", fd);
+ }
+ } else {
+ f = __intVal(fd);
+ if ((unsigned)f < FD_SETSIZE) {
+ FD_SET(f, &eset);
+ if (f > maxF) maxF = f;
+ numFds++;
+ } else {
+ if (@global(InfoPrinting) == true) {
+ fprintf(stderr, "[OS] warning: huge except-fd (0x%x) given to select\n", fd);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ t = __intVal(millis);
+ if (t) {
+ wt.tv_sec = t / 1000;
+ wt.tv_usec = (t % 1000) * 1000;
+ } else {
+ wt.tv_sec = wt.tv_usec = 0;
+ }
+
+ /*
+ * make certain, that interrupt gets us out of the select
+ * However, we must then care for moved objects.
+ */
+ __BEGIN_INTERRUPTABLE__
+ errno = 0;
+
+ if (t == 0) {
+ /*
+ * if there is no timeout time, we can stay here interruptable.
+ */
+ do {
+ ret = select(maxF+1, &rset, &wset, &eset, &wt);
+ } while ((ret < 0) && (errno == EINTR));
+ } else {
+ do {
+ ret = select(maxF+1, &rset, &wset, &eset, &wt);
+ /*
+ * for now: dont loop; if we did, we had to adjust the vt-timeval;
+ * could otherwise stay in this loop forever ...
+ * Premature ret (before the time expired) must be handled by the caller.
+ * A good solution is to update the wt-timeval and redo the select.
+ */
+ } while (0 /* (ret < 0) && (errno == EINTR) */ );
+ }
+ __END_INTERRUPTABLE__
+
+ if (ret > 0) {
+ for (i=0; i <= maxF; i++) {
+ if (FD_ISSET(i, &rset)
+ || FD_ISSET(i, &wset)
+ || FD_ISSET(i, &eset)) {
+ RETURN ( __MKSMALLINT(i) );
+ }
+ }
+ } else {
+ if (ret < 0) {
+ if (errno == EINTR) {
+ errno = 0;
+ @global(LastErrorNumber) = nil;
+ } else {
+ if (@global(InfoPrinting) == true) {
+ fprintf(stderr, "OS [info]: select errno = %d\n", errno);
+ }
+ @global(LastErrorNumber) = __MKSMALLINT(errno);
+ }
+ } else {
+ @global(LastErrorNumber) = nil;
+ }
+ }
+
+ /*
+ * Return nil (means time expired or interrupted)
+ */
+ RETURN ( nil );
}
fail: ;
@@ -12152,7 +12215,7 @@
!UnixOperatingSystem class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.174 2003-07-15 12:19:45 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.175 2003-07-15 14:03:04 cg Exp $'
! !
UnixOperatingSystem initialize!