--- a/UnixOperatingSystem.st Fri Jul 11 19:52:44 2003 +0200
+++ b/UnixOperatingSystem.st Fri Jul 11 19:53:47 2003 +0200
@@ -9645,6 +9645,211 @@
^ super readCheck:fd
!
+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..
+ 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"
+
+%{
+ fd_set rset, wset, eset;
+ struct timeval wt, et;
+ int f, maxF, i, lX, bX;
+ INT t;
+ OBJ fd, retFd;
+ int ret;
+ int count, resultCount;
+ int numFds = 0;
+#ifndef __isArrayLike
+# define __isArrayLike __isArray
+#endif
+
+ if (!__isSmallInteger(millis)) {
+ goto fail;
+ }
+ if (! __isArrayLike(resultFdArray)) {
+ goto fail;
+ }
+ resultCount = __arraySize(resultFdArray);
+
+ 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) {
+ int cnt = 0;
+ OBJ *__result = __arrayVal(resultFdArray);
+
+ 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);
+ }
+ cnt++;
+ }
+ }
+ RETURN (__MKSMALLINT(cnt));
+ } 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 0 (no filedescriptor ready)
+ */
+ RETURN (__MKSMALLINT(0));
+
+
+fail: ;
+%}.
+ "
+ timeout argument not integer,
+ or any fd-array nonNil and not an array
+ or not supported by OS
+ "
+ ^ self primitiveFailed
+!
+
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
@@ -13347,7 +13552,7 @@
!UnixOperatingSystem class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.171 2003-07-01 11:15:10 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.172 2003-07-11 17:53:47 stefan Exp $'
! !
UnixOperatingSystem initialize!