--- a/Win32OperatingSystem.st Tue Feb 28 09:32:24 2017 +0000
+++ b/Win32OperatingSystem.st Sun Mar 05 21:13:56 2017 +0000
@@ -12033,7 +12033,10 @@
//#define SELECTDEBUGWIN32
//#define SELECT3DEBUGWIN32
#define MAXHANDLE 128
- int i;
+ int i, idx;
+ INT t;
+ int numHandles;
+ DWORD res;
HANDLE hArray[MAXHANDLE+1];
int retArray[MAXHANDLE];
int readCount, writeCount, exceptCount;
@@ -12043,7 +12046,8 @@
fd_set readFds;
fd_set writeFds;
fd_set exceptFds;
- int numHandles, numSockets, numPipes;
+ int hasSockets;
+ int hasPipes;
int pass = 1; // perform up to 2 passes
if (readableResultFdArray != nil) {
@@ -12100,7 +12104,7 @@
FD_ZERO(&readFds);
FD_ZERO(&writeFds);
FD_ZERO(&exceptFds);
- numHandles = numSockets = numPipes = 0;
+ numHandles = hasSockets = hasPipes = 0;
for (i = 0; (i < readCount) && (numHandles < MAXHANDLE); i++) {
OBJ fd = __arrayVal(readFdArray)[i];
@@ -12108,7 +12112,7 @@
if (fd != nil) {
if (__Class(fd) == @global(Win32SocketHandle)) {
FD_SET (_HANDLEVal(fd), &readFds);
- numSockets++;
+ hasSockets++;
} else if (__isSmallInteger(fd)) {
DWORD canRead;
if (PeekNamedPipe(_get_osfhandle(__intVal(fd)), 0, 0, 0, &canRead, 0)) {
@@ -12122,7 +12126,7 @@
@global(LastErrorNumber) = __mkSmallInteger(EBADF);
RETURN (__mkSmallInteger(-1));
}
- numPipes++;
+ hasPipes++;
} else {
hArray [numHandles] = _HANDLEVal(fd);
retArray[numHandles] = i;
@@ -12137,7 +12141,7 @@
if (fd != nil) {
if (__Class(fd) == @global(Win32SocketHandle)) {
FD_SET (_HANDLEVal(fd), &writeFds);
- numSockets++;
+ hasSockets++;
} else if (__isSmallInteger(fd)) {
// kludge: assume that pipes can alway be written
if (*pcntW < resultSizeWritable) {
@@ -12159,7 +12163,7 @@
if (fdOrPid != nil) {
if (__Class(fdOrPid) == @global(Win32SocketHandle)) {
FD_SET (_HANDLEVal(fdOrPid), &exceptFds);
- numSockets++;
+ hasSockets++;
} else if (__isExternalAddressLike(fdOrPid)) {
// a PID
hArray [numHandles] = _HANDLEVal(fdOrPid);
@@ -12169,37 +12173,96 @@
}
}
- // +++++ 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
+ 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)) {
+ } 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;
+ }
#ifdef SELECT3DEBUGWIN32
console_printf("wait numhandles = %d timeout = %d\n", numHandles, t);
#endif
- res = __vmWait(numHandles, hArray, MAXHANDLE, (int)t);
+ res = __vmWait(numHandles, hArray, MAXHANDLE, t);
if (res == WAIT_TIMEOUT) {
#ifdef SELECT3DEBUGWIN32
- console_printf("- timeOut" );
-#endif
- goto checkSockets;
- }
- if (res == __WAIT_INTERRUPTED) {
-#ifdef SELECT3DEBUGWIN32
- console_printf("- interrupted\n" );
-#endif
+ 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;
}
@@ -12220,15 +12283,16 @@
}
}
- if ((res < 0) || (res >= numHandles)) {
+ 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");
}
- } else {
- console_printf("- res=%d error1 %d\n", res, GetLastError());
- }
+ goto done;
+ }
+ if ((res < 0) || (res >= numHandles)) {
+ console_printf("- res=%d error1 %d\n", res, GetLastError());
goto done;
}
@@ -12274,81 +12338,11 @@
#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("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
+ if (t != 0 && (hasSockets || hasPipes)) {
+ // back after timeout, maybe some sockets or pipes did wake up
// in the meantime?
pass = 2;
goto pollAgain;
- }
}
done:
@@ -12374,8 +12368,6 @@
or not supported by OS
"
^ self primitiveFailed
-
- "Modified: / 15-01-2017 / 03:04:41 / stefan"
!
setBlocking:aBoolean on:fd