summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2024-04-09 16:53:56 +0200
committerFlorian Dold <florian@dold.me>2024-04-09 16:54:05 +0200
commit6f07bb842eb622fdc786217b5e745b477c2b0b10 (patch)
tree81f7508dfb7212befd8affe93f85c5c3fee7239f
parentdc195dcc4fa5785f0a3721ea1a6af20516d6f02b (diff)
downloadquickjs-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.c78
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 */