in src/couch_quickjs/quickjs/quickjs-libc.c [2306:2397]
static int js_os_poll(JSContext *ctx)
{
JSRuntime *rt = JS_GetRuntime(ctx);
JSThreadState *ts = JS_GetRuntimeOpaque(rt);
int min_delay, count;
int64_t cur_time, delay;
JSOSRWHandler *rh;
struct list_head *el;
HANDLE handles[MAXIMUM_WAIT_OBJECTS]; // 64
/* XXX: handle signals if useful */
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;
}
}
} else {
min_delay = -1;
}
count = 0;
list_for_each(el, &ts->os_rw_handlers) {
rh = list_entry(el, JSOSRWHandler, link);
if (rh->fd == 0 && !JS_IsNull(rh->rw_func[0])) {
handles[count++] = (HANDLE)_get_osfhandle(rh->fd); // stdin
if (count == (int)countof(handles))
break;
}
}
list_for_each(el, &ts->port_list) {
JSWorkerMessageHandler *port = list_entry(el, JSWorkerMessageHandler, link);
if (JS_IsNull(port->on_message_func))
continue;
handles[count++] = port->recv_pipe->waker.handle;
if (count == (int)countof(handles))
break;
}
if (count > 0) {
DWORD ret, timeout = INFINITE;
if (min_delay != -1)
timeout = min_delay;
ret = WaitForMultipleObjects(count, handles, FALSE, timeout);
if (ret < count) {
list_for_each(el, &ts->os_rw_handlers) {
rh = list_entry(el, JSOSRWHandler, link);
if (rh->fd == 0 && !JS_IsNull(rh->rw_func[0])) {
call_handler(ctx, rh->rw_func[0]);
/* 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 (ps->waker.handle == handles[ret]) {
if (handle_posted_message(rt, ctx, port))
goto done;
}
}
}
}
} else {
Sleep(min_delay);
}
done:
return 0;
}