diff options
author | Florian Dold <florian@dold.me> | 2024-04-09 16:53:56 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2024-04-09 16:54:05 +0200 |
commit | 6f07bb842eb622fdc786217b5e745b477c2b0b10 (patch) | |
tree | 81f7508dfb7212befd8affe93f85c5c3fee7239f | |
parent | dc195dcc4fa5785f0a3721ea1a6af20516d6f02b (diff) | |
download | quickjs-tart-6f07bb842eb622fdc786217b5e745b477c2b0b10.tar.gz quickjs-tart-6f07bb842eb622fdc786217b5e745b477c2b0b10.tar.bz2 quickjs-tart-6f07bb842eb622fdc786217b5e745b477c2b0b10.zip |
event loop: attempt to handle different types of events with more fairness
-rw-r--r-- | quickjs/quickjs-libc.c | 78 |
1 files changed, 46 insertions, 32 deletions
diff --git a/quickjs/quickjs-libc.c b/quickjs/quickjs-libc.c index 96b419b..544719a 100644 --- a/quickjs/quickjs-libc.c +++ b/quickjs/quickjs-libc.c @@ -179,6 +179,9 @@ typedef struct JSThreadState { int is_worker_thread; + // used to provided fairer scheduling of event reactions + unsigned int poll_iteration_count; + struct list_head http_requests; #ifndef NO_HTTP @@ -2949,46 +2952,57 @@ static int js_os_poll(JSContext *ctx) 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; + // Start with a different event type on every iteration + // for fairness. + switch (ts->poll_iteration_count % 4) { + case 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; + } + } + /* fallthrough */ + case 1: + 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->read_fd, &rfds)) { + if (handle_posted_message(rt, ctx, port)) + 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->read_fd, &rfds)) { - if (handle_posted_message(rt, ctx, port)) - goto done; + /* fallthrough */ + case 2: + if (FD_ISSET(ts->host_pipe->read_fd, &rfds)) { + if (handle_host_message(rt, ctx)) { + goto done; } } - } - - if (FD_ISSET(ts->host_pipe->read_fd, &rfds)) { - if (handle_host_message(rt, ctx)) { - goto done; + /* fallthrough */ + case 3: + if (FD_ISSET(ts->http_pipe->read_fd, &rfds)) { + if (handle_http_message(rt, ctx)) { + goto done; + } } + /* fallthrough */ } - if (FD_ISSET(ts->http_pipe->read_fd, &rfds)) { - if (handle_http_message(rt, ctx)) { - goto done; - } - } } done: + ts->poll_iteration_count++; return 0; } #endif /* !_WIN32 */ |