aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library.js61
-rw-r--r--tests/websockets.c5
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];