@@ -554,6 +554,29 @@ var SyscallsLibrary = {
554554 var stream = SYSCALLS.getStreamFromFD(fd);
555555 return 0; // we can't do anything synchronously; the in-memory FS is already synced to
556556 },
557+ __syscall_ppoll__deps: ['__syscall_poll'],
558+ __syscall_ppoll__proxy: 'sync',
559+ __syscall_ppoll__async: 'auto',
560+ __syscall_ppoll: (fds, nfds, tmo_p, sigmaskp, sigsetsize) => {
561+ var timeout;
562+ if (tmo_p) {
563+ // musl passes a long[2] (not a struct timespec): two 4-byte values
564+ // at offsets 0 and 4 for tv_sec and tv_nsec respectively.
565+ var tv_sec = {{{ makeGetValue('tmo_p', 0, 'i32') }}};
566+ var tv_nsec = {{{ makeGetValue('tmo_p', 4, 'i32') }}};
567+ timeout = tv_sec * 1000 + (tv_nsec / 1000000);
568+ } else {
569+ timeout = -1;
570+ }
571+ return ___syscall_poll(fds, nfds, timeout);
572+ },
573+ // NOTE: __async is intentionally NOT set here. The compiler-generated
574+ // Asyncify.handleAsync wrapper conflicts with PROXY_SYNC_ASYNC: when
575+ // poll is called from the proxy path on the main thread, the Promise
576+ // return triggers an ASYNCIFY unwind that destroys the proxy task
577+ // execution, causing the worker to hang. Instead, we handle ASYNCIFY
578+ // manually inside the function via Asyncify.handleAsync only when NOT
579+ // in a proxied context.
557580 __syscall_poll__proxy: 'sync',
558581 __syscall_poll__async: 'auto',
559582 __syscall_poll: (fds, nfds, timeout) => {
0 commit comments