--- a/Win32OperatingSystem.st Tue Dec 06 14:26:48 2016 +0100
+++ b/Win32OperatingSystem.st Tue Dec 06 18:46:54 2016 +0100
@@ -978,7 +978,6 @@
"Modified: 7.1.1997 / 19:36:11 / stefan"
! !
-
!Win32OperatingSystem class methodsFor:'OS signal constants'!
sigABRT
@@ -12022,10 +12021,7 @@
//#define SELECTDEBUGWIN32
//#define SELECT3DEBUGWIN32
#define MAXHANDLE 128
- int i, idx;
- INT t;
- int numHandles;
- DWORD res;
+ int i;
HANDLE hArray[MAXHANDLE+1];
int retArray[MAXHANDLE];
int readCount, writeCount, exceptCount;
@@ -12035,315 +12031,324 @@
fd_set readFds;
fd_set writeFds;
fd_set exceptFds;
- int hasSockets;
- int hasPipes;
+ int numHandles, numSockets, numPipes;
int pass = 1; // perform up to 2 passes
if (readableResultFdArray != nil) {
- if (! __isArrayLike(readableResultFdArray)) {
- goto fail;
- }
- resultSizeReadable = __arraySize(readableResultFdArray);
+ if (! __isArrayLike(readableResultFdArray)) {
+ goto fail;
+ }
+ resultSizeReadable = __arraySize(readableResultFdArray);
}
if (writableResultFdArray != nil) {
- if (! __isArrayLike(writableResultFdArray)) {
- goto fail;
- }
- resultSizeWritable = __arraySize(writableResultFdArray);
- if (readableResultFdArray == writableResultFdArray) {
- // allow common result set for read/write/except
- pcntW = &cntR;
- }
+ if (! __isArrayLike(writableResultFdArray)) {
+ goto fail;
+ }
+ resultSizeWritable = __arraySize(writableResultFdArray);
+ if (readableResultFdArray == writableResultFdArray) {
+ // allow common result set for read/write/except
+ pcntW = &cntR;
+ }
}
if (exceptionResultFdArray != nil) {
- if (! __isArrayLike(exceptionResultFdArray)) {
- goto fail;
- }
- resultSizeException = __arraySize(exceptionResultFdArray);
- if (exceptionResultFdArray == readableResultFdArray) {
- // allow common result set for read/write/except
- pcntE = &cntR;
- } else if (exceptionResultFdArray == writableResultFdArray) {
- pcntE = &cntW;
- }
+ if (! __isArrayLike(exceptionResultFdArray)) {
+ goto fail;
+ }
+ resultSizeException = __arraySize(exceptionResultFdArray);
+ if (exceptionResultFdArray == readableResultFdArray) {
+ // allow common result set for read/write/except
+ pcntE = &cntR;
+ } else if (exceptionResultFdArray == writableResultFdArray) {
+ pcntE = &cntW;
+ }
}
if (__isNonNilObject(readFdArray)) {
- if (! __isArrayLike(readFdArray)) goto fail;
- readCount = __arraySize(readFdArray);
+ if (! __isArrayLike(readFdArray)) goto fail;
+ readCount = __arraySize(readFdArray);
} else {
- readCount = 0;
+ readCount = 0;
}
if (__isNonNilObject(writeFdArray)) {
- if (! __isArrayLike(writeFdArray)) goto fail;
- writeCount = __arraySize(writeFdArray);
+ if (! __isArrayLike(writeFdArray)) goto fail;
+ writeCount = __arraySize(writeFdArray);
} else {
- writeCount = 0;
+ writeCount = 0;
}
if (__isNonNilObject(exceptFdArray)) {
- if (! __isArrayLike(exceptFdArray)) goto fail;
- exceptCount = __arraySize(exceptFdArray);
+ if (! __isArrayLike(exceptFdArray)) goto fail;
+ exceptCount = __arraySize(exceptFdArray);
} else {
- exceptCount = 0;
+ exceptCount = 0;
}
pollAgain:
FD_ZERO(&readFds);
FD_ZERO(&writeFds);
FD_ZERO(&exceptFds);
- numHandles = hasSockets = hasPipes = 0;
+ numHandles = numSockets = numPipes = 0;
for (i = 0; (i < readCount) && (numHandles < MAXHANDLE); i++) {
- OBJ fd = __arrayVal(readFdArray)[i];
-
- if (fd != nil) {
- if (__Class(fd) == @global(Win32SocketHandle)) {
- FD_SET (_HANDLEVal(fd), &readFds);
- hasSockets++;
- } else if (__isSmallInteger(fd)) {
- DWORD canRead;
- if (PeekNamedPipe(_get_osfhandle(__intVal(fd)), 0, 0, 0, &canRead, 0)) {
- if (canRead > 0) {
- if (*pcntR < resultSizeReadable) {
- __arrayVal(readableResultFdArray)[*pcntR] = fd;
- }
- (*pcntR)++; cntAll++;
- }
- } else {
- @global(LastErrorNumber) = __mkSmallInteger(EBADF);
- RETURN (__mkSmallInteger(-1));
- }
- hasPipes++;
- } else {
- hArray [numHandles] = _HANDLEVal(fd);
- retArray[numHandles] = i;
- ++numHandles;
- }
- }
+ OBJ fd = __arrayVal(readFdArray)[i];
+
+ if (fd != nil) {
+ if (__Class(fd) == @global(Win32SocketHandle)) {
+ FD_SET (_HANDLEVal(fd), &readFds);
+ numSockets++;
+ } else if (__isSmallInteger(fd)) {
+ DWORD canRead;
+ if (PeekNamedPipe(_get_osfhandle(__intVal(fd)), 0, 0, 0, &canRead, 0)) {
+ if (canRead > 0) {
+ if (*pcntR < resultSizeReadable) {
+ __arrayVal(readableResultFdArray)[*pcntR] = fd;
+ }
+ (*pcntR)++; cntAll++;
+ }
+ } else {
+ @global(LastErrorNumber) = __mkSmallInteger(EBADF);
+ RETURN (__mkSmallInteger(-1));
+ }
+ numPipes++;
+ } else {
+ hArray [numHandles] = _HANDLEVal(fd);
+ retArray[numHandles] = i;
+ ++numHandles;
+ }
+ }
}
for (i = 0; (i < writeCount) && (numHandles < MAXHANDLE); i++) {
- OBJ fd = __arrayVal(writeFdArray)[i];
-
- if (fd != nil) {
- if (__Class(fd) == @global(Win32SocketHandle)) {
- FD_SET (_HANDLEVal(fd), &writeFds);
- hasSockets++;
- } else if (__isSmallInteger(fd)) {
- // kludge: assume that pipes can alway be written
- if (*pcntW < resultSizeWritable) {
- __arrayVal(writableResultFdArray)[*pcntW] = fd;
- }
- (*pcntW)++; cntAll++;
- // there is no pipe to check
- } else {
- hArray [numHandles] = _HANDLEVal(fd);
- retArray[numHandles] = i + 10000;
- ++numHandles;
- }
- }
+ OBJ fd = __arrayVal(writeFdArray)[i];
+
+ if (fd != nil) {
+ if (__Class(fd) == @global(Win32SocketHandle)) {
+ FD_SET (_HANDLEVal(fd), &writeFds);
+ numSockets++;
+ } else if (__isSmallInteger(fd)) {
+ // kludge: assume that pipes can alway be written
+ if (*pcntW < resultSizeWritable) {
+ __arrayVal(writableResultFdArray)[*pcntW] = fd;
+ }
+ (*pcntW)++; cntAll++;
+ // there is no pipe to check
+ } else {
+ hArray [numHandles] = _HANDLEVal(fd);
+ retArray[numHandles] = i + 10000;
+ ++numHandles;
+ }
+ }
}
for (i = 0; (i < exceptCount) && (numHandles < MAXHANDLE); i++) {
- OBJ fdOrPid = __arrayVal(exceptFdArray)[i];
-
- if (fdOrPid != nil) {
- if (__Class(fdOrPid) == @global(Win32SocketHandle)) {
- FD_SET (_HANDLEVal(fdOrPid), &exceptFds);
- hasSockets++;
- } else if (__isExternalAddressLike(fdOrPid)) {
- // a PID
- hArray [numHandles] = _HANDLEVal(fdOrPid);
- retArray[numHandles] = i + 20000;
- ++numHandles;
- }
- }
- }
-
- if (hasSockets) {
- struct timeval tv = {0, 0};
- int nReady;
-
-#ifdef SELECT3DEBUGWIN32
- console_printf("select hasSockets = %d\n", hasSockets);
-#endif
- nReady = select(1 , &readFds, &writeFds, &exceptFds, &tv); // first parameter to select is ignored in windows
- if (nReady < 0) {
-#ifdef SELECTDEBUGWIN32
- console_printf("error in select %d %d\n", nReady, GetLastError());
-#endif
- @global(LastErrorNumber) = __mkSmallInteger(EBADF);
- RETURN (__mkSmallInteger(-1));
- }
- if (nReady > 0) {
-#ifdef SELECT3DEBUGWIN32
- console_printf("select nReady %d of %d\n", nReady, hasSockets);
-#endif
- for (i = 0; i < readCount; i++) {
- OBJ fd = __arrayVal(readFdArray)[i];
- if ((__Class(fd) == @global(Win32SocketHandle)) && FD_ISSET(_HANDLEVal(fd), &readFds)) {
- if (*pcntR < resultSizeReadable) {
- __arrayVal(readableResultFdArray)[*pcntR] = fd;
- __STORE(readableResultFdArray, fd);
- }
- (*pcntR)++; cntAll++;
- }
- }
- for (i = 0; i < writeCount; i++) {
- OBJ fd = __arrayVal(writeFdArray)[i];
- if ((__Class(fd) == @global(Win32SocketHandle)) && FD_ISSET(_HANDLEVal(fd), &writeFds)) {
- if (*pcntW < resultSizeWritable) {
- __arrayVal(writableResultFdArray)[*pcntW] = fd;
- __STORE(writableResultFdArray, fd);
- }
- (*pcntW)++; cntAll++;
- }
- }
- for (i = 0; i < exceptCount; i++) {
- OBJ fd = __arrayVal(exceptFdArray)[i];
- if ((__Class(fd) == @global(Win32SocketHandle)) && FD_ISSET(_HANDLEVal(fd), &exceptFds)) {
- if (*pcntE < resultSizeException) {
- __arrayVal(exceptionResultFdArray)[*pcntE] = fd;
- __STORE(exceptionResultFdArray, fd);
- }
- (*pcntE)++; cntAll++;
- }
- }
-
- }
- }
- if (pass > 1) // perform maximum 2 passes
- goto done;
-
- if (cntAll) {
- // check for other handles and return immediately, no timeout
- t = 0;
- } else {
- if (__isSmallInteger(millis)) {
- t = __intVal(millis);
-
- if (t <= 0 && numHandles == 0) {
- RETURN (__mkSmallInteger(0));
- }
- } else {
- t = INFINITE;
- }
- }
-
- if (numHandles == 0 && t == 0) {
- // nothing to do and no wait
- goto done;
- }
+ OBJ fdOrPid = __arrayVal(exceptFdArray)[i];
+
+ if (fdOrPid != nil) {
+ if (__Class(fdOrPid) == @global(Win32SocketHandle)) {
+ FD_SET (_HANDLEVal(fdOrPid), &exceptFds);
+ numSockets++;
+ } else if (__isExternalAddressLike(fdOrPid)) {
+ // a PID
+ hArray [numHandles] = _HANDLEVal(fdOrPid);
+ retArray[numHandles] = i + 20000;
+ ++numHandles;
+ }
+ }
+ }
+
+ // +++++ checking for Windows Handles +++++++++++++++++++++++++++++++++++++++++
+ if (numHandles != 0) {
+ DWORD res;
+ int idx;
+ INT t;
+
+ if (numSockets || pass > 1) {
+ // do not wait - wait when checking for sockets
+ t = 0;
+ } else if (__isSmallInteger(millis)) {
+ t = __intVal(millis);
+ } else {
+ t = INFINITE;
+ }
#ifdef SELECT3DEBUGWIN32
- console_printf("wait numhandles = %d timeout = %d\n", numHandles, t);
-#endif
-
- res = __vmWait(numHandles, hArray, MAXHANDLE, t);
-
- if (res == WAIT_TIMEOUT) {
+ console_printf("wait numhandles = %d timeout = %d\n", numHandles, t);
+#endif
+
+ res = __vmWait(numHandles, hArray, MAXHANDLE, (int)t);
+
+ if (res == WAIT_TIMEOUT) {
#ifdef SELECT3DEBUGWIN32
- console_printf("- timeOut; ret nil\n" );
-#endif
- if (t != 0 && (hasSockets || hasPipes)) {
- // if not a single handle is ready, poll sockets an pipes again
- pass = 2;
- goto pollAgain;
- }
- goto done;
- }
-
- if (res == WAIT_FAILED) {
+ console_printf("- timeOut" );
+#endif
+ goto checkSockets;
+ }
+ if (res == __WAIT_INTERRUPTED) {
+#ifdef SELECT3DEBUGWIN32
+ console_printf("- interrupted\n" );
+#endif
+ goto done;
+ }
+
+ if (res == WAIT_FAILED) {
#ifdef SELECT2DEBUGWIN32
- console_printf("- error %d (last %d); ret -1\n", __threadErrno, GetLastError());
-#endif
- if (__threadErrno == EINTR) {
- @global(LastErrorNumber) = nil;
- RETURN (__mkSmallInteger(0));
- } else {
- if (@global(InfoPrinting) == true) {
-// console_fprintf(stderr, "Win32OS [info]: select errno = %d (last %d)\n", __threadErrno, GetLastError());
- console_printf("Win32OS [info]: select errno = %d (last %d)\n", __threadErrno, GetLastError());
- }
- @global(LastErrorNumber) = __mkSmallInteger(EBADF);
- RETURN (__mkSmallInteger(-1));
- }
- }
-
- if (numHandles) {
- if (res == numHandles) {
- // vmwait() added an IRQ event to the handles, and this one has been triggered
- if (1 /* @global(InfoPrinting) == true */) {
- console_fprintf(stderr, "Win32OS [info]: plugIn event has been handled\n");
- }
- goto done;
- }
- if ((res < 0) || (res >= numHandles)) {
- console_printf("- res=%d error1 %d\n", res, GetLastError());
- goto done;
- }
-
- idx = retArray[res];
- cntAll++;
+ console_printf("- error %d (last %d); ret -1\n", __threadErrno, GetLastError());
+#endif
+ if (__threadErrno == EINTR) {
+ @global(LastErrorNumber) = nil;
+ RETURN (__mkSmallInteger(0));
+ } else {
+ if (@global(InfoPrinting) == true) {
+// console_fprintf(stderr, "Win32OS [info]: select errno = %d (last %d)\n", __threadErrno, GetLastError());
+ console_printf("Win32OS [info]: select errno = %d (last %d)\n", __threadErrno, GetLastError());
+ }
+ @global(LastErrorNumber) = __mkSmallInteger(EBADF);
+ RETURN (__mkSmallInteger(-1));
+ }
+ }
+
+ if (res == numHandles) {
+ // vmwait() added an IRQ event to the handles, and this one has been triggered
+ if (1 /* @global(InfoPrinting) == true */) {
+ console_fprintf(stderr, "Win32OS [info]: plugIn event has been handled\n");
+ }
+ goto done;
+ }
+ if ((res < 0) || (res >= numHandles)) {
+ console_printf("- res=%d error1 %d\n", res, GetLastError());
+ goto done;
+ }
+
+ idx = retArray[res];
+ cntAll++;
#ifdef SELECTDEBUGWIN32
- console_printf("wait Handles res %d idx %d numHandles %d --- ", res, idx, numHandles);
-#endif
- if (idx < 10000) {
- if (*pcntR < resultSizeReadable) {
- OBJ temp = __arrayVal(readFdArray)[idx];
- __arrayVal(readableResultFdArray)[*pcntR] = temp;
- __STORE(readableResultFdArray, temp);
+ console_printf("wait Handles res %d idx %d numHandles %d --- ", res, idx, numHandles);
+#endif
+ if (idx < 10000) {
+ if (*pcntR < resultSizeReadable) {
+ OBJ temp = __arrayVal(readFdArray)[idx];
+ __arrayVal(readableResultFdArray)[*pcntR] = temp;
+ __STORE(readableResultFdArray, temp);
#ifdef SELECTDEBUGWIN32
- console_printf("read ready: %x\n", __externalAddressVal(temp));
-#endif
- (*pcntR)++;
- }
- } else if (idx < 20000) {
- if (*pcntW < resultSizeWritable) {
- OBJ temp = __arrayVal(writeFdArray)[idx-10000];
- __arrayVal(writableResultFdArray)[*pcntW] = temp;
- __STORE(writableResultFdArray, temp);
+ console_printf("read ready: %x\n", __externalAddressVal(temp));
+#endif
+ (*pcntR)++;
+ }
+ } else if (idx < 20000) {
+ if (*pcntW < resultSizeWritable) {
+ OBJ temp = __arrayVal(writeFdArray)[idx-10000];
+ __arrayVal(writableResultFdArray)[*pcntW] = temp;
+ __STORE(writableResultFdArray, temp);
+#ifdef SELECTDEBUGWIN32
+ console_printf("write ready: %x\n", temp);
+#endif
+ (*pcntW)++;
+ }
+ } else {
+ if (*pcntE < resultSizeException) {
+ OBJ temp = __arrayVal(exceptFdArray)[idx-20000];
+ __arrayVal(exceptionResultFdArray)[*pcntE] = temp;
+ __STORE(exceptionResultFdArray, temp);
+#ifdef SELECTDEBUGWIN32
+ console_printf("except ready: %x\n", temp);
+#endif
+ (*pcntE)++;
+ }
#ifdef SELECTDEBUGWIN32
- console_printf("write ready: %x\n", temp);
-#endif
- (*pcntW)++;
- }
- } else {
- if (*pcntE < resultSizeException) {
- OBJ temp = __arrayVal(exceptFdArray)[idx-20000];
- __arrayVal(exceptionResultFdArray)[*pcntE] = temp;
- __STORE(exceptionResultFdArray, temp);
+ else
+ console_printf("cntE: %d, resultSizeException: %d\n", *pcntE, resultSizeException);
+#endif
+ }
+ }
+
+
+// ++++++++++ Check Sockets +++++++++++++++++++++++++++++++++++
+checkSockets:
+ if (pass > 1) // perform maximum 2 passes
+ goto done;
+
+ if (numSockets) {
+ struct timeval tv = {0, 0};
+ struct timeval *tvp = &tv;
+ int nReady;
+
+ // do not wait, if there are threads that can be resumed
+ if (!__vmTestIfAnyThreadMustBeResumed() && cntAll == 0) {
+ // no ready handles found yet - do wait
+ if (__isSmallInteger(millis)) {
+ tv.tv_usec = __intVal(millis) * 1000;
+ } else {
+ // no timeout
+ tvp = 0;
+ }
+ }
+
+#ifdef SELECT3DEBUGWIN32
+ console_printf("select numSockets = %d\n", numSockets);
+#endif
+ nReady = select(1 , &readFds, &writeFds, &exceptFds, tvp); // first parameter to select is ignored in windows
+ if (nReady < 0) {
#ifdef SELECTDEBUGWIN32
- console_printf("except ready: %x\n", temp);
-#endif
- (*pcntE)++;
- }
-#ifdef SELECTDEBUGWIN32
- else
- console_printf("cntE: %d, resultSizeException: %d\n", *pcntE, resultSizeException);
-#endif
- }
- }
- if (t != 0 && (hasSockets || hasPipes)) {
- // back after timeout, maybe some sockets or pipes did wake up
- // in the meantime?
- pass = 2;
- goto pollAgain;
+ console_printf("error in select %d %d\n", nReady, GetLastError());
+#endif
+ @global(LastErrorNumber) = __mkSmallInteger(EBADF);
+ RETURN (__mkSmallInteger(-1));
+ }
+ if (nReady > 0) {
+#ifdef SELECT3DEBUGWIN32
+ console_printf("select nReady %d of %d\n", nReady, numSockets);
+#endif
+ for (i = 0; i < readCount; i++) {
+ OBJ fd = __arrayVal(readFdArray)[i];
+ if ((__Class(fd) == @global(Win32SocketHandle)) && FD_ISSET(_HANDLEVal(fd), &readFds)) {
+ if (*pcntR < resultSizeReadable) {
+ __arrayVal(readableResultFdArray)[*pcntR] = fd;
+ __STORE(readableResultFdArray, fd);
+ }
+ (*pcntR)++; cntAll++;
+ }
+ }
+ for (i = 0; i < writeCount; i++) {
+ OBJ fd = __arrayVal(writeFdArray)[i];
+ if ((__Class(fd) == @global(Win32SocketHandle)) && FD_ISSET(_HANDLEVal(fd), &writeFds)) {
+ if (*pcntW < resultSizeWritable) {
+ __arrayVal(writableResultFdArray)[*pcntW] = fd;
+ __STORE(writableResultFdArray, fd);
+ }
+ (*pcntW)++; cntAll++;
+ }
+ }
+ for (i = 0; i < exceptCount; i++) {
+ OBJ fd = __arrayVal(exceptFdArray)[i];
+ if ((__Class(fd) == @global(Win32SocketHandle)) && FD_ISSET(_HANDLEVal(fd), &exceptFds)) {
+ if (*pcntE < resultSizeException) {
+ __arrayVal(exceptionResultFdArray)[*pcntE] = fd;
+ __STORE(exceptionResultFdArray, fd);
+ }
+ (*pcntE)++; cntAll++;
+ }
+ }
+ }
+ if (tvp && tv.tv_usec != 0 && (numHandles != 0 || numPipes != 0)) {
+ // back after timeout, maybe some handles or pipes did wake up
+ // in the meantime?
+ pass = 2;
+ goto pollAgain;
+ }
}
done:
/* add a delimiter */
if (*pcntR < resultSizeReadable) {
- __arrayVal(readableResultFdArray)[*pcntR] = nil;
+ __arrayVal(readableResultFdArray)[*pcntR] = nil;
}
if (*pcntW < resultSizeWritable) {
- __arrayVal(writableResultFdArray)[*pcntW] = nil;
+ __arrayVal(writableResultFdArray)[*pcntW] = nil;
}
if (*pcntE < resultSizeException) {
- __arrayVal(exceptionResultFdArray)[*pcntE] = nil;
+ __arrayVal(exceptionResultFdArray)[*pcntE] = nil;
}
@global(LastErrorNumber) = nil;