diff options
-rw-r--r-- | src/library.js | 61 | ||||
-rw-r--r-- | tests/websockets.c | 5 |
2 files changed, 52 insertions, 14 deletions
diff --git a/src/library.js b/src/library.js index 900b3fee..24f241c7 100644 --- a/src/library.js +++ b/src/library.js @@ -7244,23 +7244,56 @@ LibraryManager.library = { }, select: function(nfds, readfds, writefds, exceptfds, timeout) { - // only readfds are supported, not writefds or exceptfds + // readfds are supported, + // writefds checks socket open status + // exceptfds not supported // timeout is always 0 - fully async - assert(!writefds && !exceptfds); - var ret = 0; - var l = {{{ makeGetValue('readfds', 0, 'i32') }}}; - var h = {{{ makeGetValue('readfds', 4, 'i32') }}}; - nfds = Math.min(64, nfds); // fd sets have 64 bits - for (var fd = 0; fd < nfds; fd++) { - var bit = fd % 32, int = fd < 32 ? l : h; - if (int & (1 << bit)) { - // index is in the set, check if it is ready for read - var info = Sockets.fds[fd]; - if (!info) continue; - if (info.hasData()) ret++; + assert(!exceptfds); + + function canRead(info) { + // make sure hasData exists. + // we do create it when the socket is connected, + // but other implementations may create it lazily + return info.hasData && info.hasData(); + } + + function canWrite(info) { + // make sure socket exists. + // we do create it when the socket is connected, + // but other implementations may create it lazily + return info.socket && (info.socket.readyState == info.socket.OPEN); + } + + function checkfds(nfds, fds, can) { + if (!fds) return 0; + + var bitsSet = 0; + var dstLow = 0; + var dstHigh = 0; + var srcLow = {{{ makeGetValue('fds', 0, 'i32') }}}; + var srcHigh = {{{ makeGetValue('fds', 4, 'i32') }}}; + nfds = Math.min(64, nfds); // fd sets have 64 bits + + for (var fd = 0; fd < nfds; fd++) { + var mask = 1 << (fd % 32), int = fd < 32 ? srcLow : srcHigh; + if (int & mask) { + // index is in the set, check if it is ready for read + var info = Sockets.fds[fd]; + if (info && can(info)) { + // set bit + fd < 32 ? (dstLow = dstLow | mask) : (dstHigh = dstHigh | mask); + bitsSet++; + } + } } + + {{{ makeSetValue('fds', 0, 'dstLow', 'i32') }}}; + {{{ makeSetValue('fds', 4, 'dstHigh', 'i32') }}}; + return bitsSet; } - return ret; + + return checkfds(nfds, readfds, canRead) + + checkfds(nfds, writefds, canWrite); }, // pty.h diff --git a/tests/websockets.c b/tests/websockets.c index 59acbd69..192933ac 100644 --- a/tests/websockets.c +++ b/tests/websockets.c @@ -27,14 +27,19 @@ unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) assert(select(64, &sett, NULL, NULL, NULL) == 0); // empty set FD_SET(sock, &sett); assert(select(0, &sett, NULL, NULL, NULL) == 0); // max FD to check is 0 + assert(FD_ISSET(sock, &sett) == 0); + FD_SET(sock, &sett); int select_says_yes = select(64, &sett, NULL, NULL, NULL); // ioctl check for IO int bytes; if (ioctl(sock, FIONREAD, &bytes) || bytes == 0) { not_always_data = 1; + assert(FD_ISSET(sock, &sett) == 0); return 0; } + + assert(FD_ISSET(sock, &sett)); assert(select_says_yes); // ioctl must agree with select char buffer[1024]; |