Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,15 @@ See docs/process.md for more on how version tagging works.
- The `PThread.runningWorkers` field was removed from the `PThread` object.
If you have JS code that was depending on this you can transition to using the
`PThread.pthreads` object. (#26998)
- The select() and poll() syscalls now fail with EINTR when no FDs are active
and they are asked to block in a build that does not support blocking (i.e.
now JSPI or ASYNCIFY). Previously they would return 0 but without any result
FSs set (i.e. as if the timeout at expired). (#27049)

5.0.7 - 04/30/26
----------------
- mimalloc was updated to 3.3.1. (#26696)
- The `WASM_JS_TYPES` setting was removed, as the corresponsing propsal was
- The `WASM_JS_TYPES` setting was removed, as the corresponding proposal was
pushed back to phase 1. (#26739)
- The `-sDETERMINISTIC` setting was removed. This setting just injected
`src/deterministic.js` as a `--pre-js`. For now, this file remains part of
Expand Down
7 changes: 6 additions & 1 deletion src/lib/libsyscall.js
Original file line number Diff line number Diff line change
Expand Up @@ -658,9 +658,14 @@ var SyscallsLibrary = {
}
#endif

if (!count && timeout) {
// We cannot actually block here since we are not in an async context,
// so return -EINTR, as if we were inturrupted by a signal.
#if ASSERTIONS
if (!count && timeout != 0) warnOnce('non-zero poll() timeout not supported: ' + timeout)
warnOnce('non-zero poll() timeout not supported: ' + timeout)
#endif
return -{{{ cDefs.EINTR }}};
}
return count;
},
__syscall_getcwd__deps: ['$lengthBytesUTF8', '$stringToUTF8'],
Expand Down
4 changes: 2 additions & 2 deletions system/lib/libc/musl/src/select/select.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict

if (s<0 || us<0) return __syscall_ret(-EINVAL);
#ifdef __EMSCRIPTEN__
return emscripten_select(n, rfds, wfds, efds, tv);
return __syscall_ret(emscripten_select(n, rfds, wfds, efds, tv));
#else
if (us/1000000 > max_time - s) {
s = max_time;
Expand Down Expand Up @@ -85,7 +85,7 @@ static int emscripten_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set
int rtn = __syscall_poll((intptr_t)fds, n, timeout);
if (rtn < 0) {
free(fds);
return -1;
return rtn;
}

// Part 2: Translate the result of poll into the results of select();
Expand Down
38 changes: 38 additions & 0 deletions test/core/test_pipe_select.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#ifdef __EMSCRIPTEN__
#include <emscripten/threading.h>
#endif

int pipe_a[2];

Expand Down Expand Up @@ -35,6 +39,40 @@ int main() {
assert(get_available(pipe_a[0]) == strlen(t));
assert(get_available(pipe_a[1]) == strlen(t));



// Test select with timeout when no FDs are ready
{
int pipe_b[2];
assert(pipe(pipe_b) == 0);

fd_set fds;
FD_ZERO(&fds);
FD_SET(pipe_b[0], &fds);
struct timeval tv = {0, 10000}; // 10ms

#ifdef __EMSCRIPTEN__
if (emscripten_is_main_runtime_thread()) {
printf("Main thread: expecting EINTR\n");
int res = select(pipe_b[0] + 1, &fds, NULL, NULL, &tv);
assert(res == -1);
assert(errno == EINTR);
} else {
printf("Worker thread: expecting timeout\n");
int res = select(pipe_b[0] + 1, &fds, NULL, NULL, &tv);
assert(res == 0);
}
#else
// Native: should timeout
printf("Native: expecting timeout\n");
int res = select(pipe_b[0] + 1, &fds, NULL, NULL, &tv);
assert(res == 0);
#endif

close(pipe_b[0]);
close(pipe_b[1]);
}

close(pipe_a[0]);
close(pipe_a[1]);
return 0;
Expand Down
11 changes: 8 additions & 3 deletions test/sockets/test_sockets_partial_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,14 @@ void iter() {
FD_SET(sockfd, &fdr);
res = select(64, &fdr, NULL, NULL, NULL);
if (res == -1) {
perror("select failed");
finish(EXIT_FAILURE);
} else if (!FD_ISSET(sockfd, &fdr)) {
if (errno != EINTR) {
perror("select failed");
finish(EXIT_FAILURE);
}
return;
}

if (!FD_ISSET(sockfd, &fdr)) {
return;
}

Expand Down
3 changes: 3 additions & 0 deletions test/sockets/test_sockets_partial_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ void iter() {
if (clientfd) FD_SET(clientfd, &fdw);
res = select(64, &fdr, &fdw, NULL, NULL);
if (res == -1) {
if (errno == EINTR) {
return;
}
perror("select failed");
exit(EXIT_SUCCESS);
}
Expand Down
Loading