in src/couch_quickjs/quickjs/quickjs-libc.c [2401:2511]
static int js_os_poll(JSContext *ctx)
{
JSRuntime *rt = JS_GetRuntime(ctx);
JSThreadState *ts = JS_GetRuntimeOpaque(rt);
int ret, fd_max, min_delay;
int64_t cur_time, delay;
fd_set rfds, wfds;
JSOSRWHandler *rh;
struct list_head *el;
struct timeval tv, *tvp;
/* only check signals in the main thread */
if (!ts->recv_pipe &&
unlikely(os_pending_signals != 0)) {
JSOSSignalHandler *sh;
uint64_t mask;
list_for_each(el, &ts->os_signal_handlers) {
sh = list_entry(el, JSOSSignalHandler, link);
mask = (uint64_t)1 << sh->sig_num;
if (os_pending_signals & mask) {
os_pending_signals &= ~mask;
call_handler(ctx, sh->func);
return 0;
}
}
}
if (list_empty(&ts->os_rw_handlers) && list_empty(&ts->os_timers) &&
list_empty(&ts->port_list))
return -1; /* no more events */
if (!list_empty(&ts->os_timers)) {
cur_time = get_time_ms();
min_delay = 10000;
list_for_each(el, &ts->os_timers) {
JSOSTimer *th = list_entry(el, JSOSTimer, link);
delay = th->timeout - cur_time;
if (delay <= 0) {
JSValue func;
/* the timer expired */
func = th->func;
th->func = JS_UNDEFINED;
free_timer(rt, th);
call_handler(ctx, func);
JS_FreeValue(ctx, func);
return 0;
} else if (delay < min_delay) {
min_delay = delay;
}
}
tv.tv_sec = min_delay / 1000;
tv.tv_usec = (min_delay % 1000) * 1000;
tvp = &tv;
} else {
tvp = NULL;
}
FD_ZERO(&rfds);
FD_ZERO(&wfds);
fd_max = -1;
list_for_each(el, &ts->os_rw_handlers) {
rh = list_entry(el, JSOSRWHandler, link);
fd_max = max_int(fd_max, rh->fd);
if (!JS_IsNull(rh->rw_func[0]))
FD_SET(rh->fd, &rfds);
if (!JS_IsNull(rh->rw_func[1]))
FD_SET(rh->fd, &wfds);
}
list_for_each(el, &ts->port_list) {
JSWorkerMessageHandler *port = list_entry(el, JSWorkerMessageHandler, link);
if (!JS_IsNull(port->on_message_func)) {
JSWorkerMessagePipe *ps = port->recv_pipe;
fd_max = max_int(fd_max, ps->waker.read_fd);
FD_SET(ps->waker.read_fd, &rfds);
}
}
ret = select(fd_max + 1, &rfds, &wfds, NULL, tvp);
if (ret > 0) {
list_for_each(el, &ts->os_rw_handlers) {
rh = list_entry(el, JSOSRWHandler, link);
if (!JS_IsNull(rh->rw_func[0]) &&
FD_ISSET(rh->fd, &rfds)) {
call_handler(ctx, rh->rw_func[0]);
/* must stop because the list may have been modified */
goto done;
}
if (!JS_IsNull(rh->rw_func[1]) &&
FD_ISSET(rh->fd, &wfds)) {
call_handler(ctx, rh->rw_func[1]);
/* must stop because the list may have been modified */
goto done;
}
}
list_for_each(el, &ts->port_list) {
JSWorkerMessageHandler *port = list_entry(el, JSWorkerMessageHandler, link);
if (!JS_IsNull(port->on_message_func)) {
JSWorkerMessagePipe *ps = port->recv_pipe;
if (FD_ISSET(ps->waker.read_fd, &rfds)) {
if (handle_posted_message(rt, ctx, port))
goto done;
}
}
}
}
done:
return 0;
}