From 6a3987d418bc764a71fee61934e21d6de3fc6d35 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 23 Jan 2026 20:26:52 +0000 Subject: [PATCH] Fix DFS simulation infinite loop due to time event scheduling issues Three related issues were causing the simulation to get stuck: 1. Network events (connect, disconnect, send_data) were scheduled with relative times instead of absolute times, causing events to be scheduled in the past once simulation time exceeded 10-100ms. 2. When DATA events couldn't be fully consumed (receiver buffer full), they stayed at their original time, preventing time from advancing. Now they are rescheduled to current_time + 10ms. 3. When poll_timeout was 0, WAKEUP events were created at current_time, causing an infinite loop where time never advanced. Now timeout=0 sets timedout immediately without creating an event. --- quakey/src/quakey.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/quakey/src/quakey.c b/quakey/src/quakey.c index 29eb06b..4f1905a 100644 --- a/quakey/src/quakey.c +++ b/quakey/src/quakey.c @@ -969,8 +969,10 @@ static void host_init(Host *host, Sim *sim, QuakeySpawn config, char *arg) TODO; } - if (host->poll_timeout > -1) + if (host->poll_timeout > 0) time_event_wakeup(host->sim, host->sim->current_time + (Nanos)host->poll_timeout * 1000000ULL, host); + else if (host->poll_timeout == 0) + host->timedout = true; // Immediate timeout, don't create event at current_time } static void host_free(Host *host) @@ -1158,8 +1160,10 @@ static void host_update(Host *host) TODO; } - if (host->poll_timeout > -1) + if (host->poll_timeout > 0) time_event_wakeup(host->sim, host->sim->current_time + (Nanos)host->poll_timeout * 1000000ULL, host); + else if (host->poll_timeout == 0) + host->timedout = true; // Immediate timeout, don't create event at current_time } static bool host_has_addr(Host *host, Addr addr) @@ -1279,7 +1283,7 @@ static int host_close(Host *host, int desc_idx, bool expect_socket) } if (host->desc[desc_idx].type == DESC_SOCKET_C) - time_event_disconnect(host->sim, 10000000, &host->desc[desc_idx], false); + time_event_disconnect(host->sim, host->sim->current_time + 10000000, &host->desc[desc_idx], false); desc_free(&host->desc[desc_idx], false); host->num_desc--; @@ -1505,7 +1509,7 @@ static int host_connect(Host *host, int desc_idx, // TODO: some percent of times connect() should resolve immediately - time_event_connect(host->sim, 100000000, desc); + time_event_connect(host->sim, host->sim->current_time + 100000000, desc); desc->connect_addr = addr; desc->connect_port = port; @@ -1658,7 +1662,7 @@ static int send_inner(Desc *desc, char *src, int len) if (ret == 0) return HOST_ERROR_WOULDBLOCK; - time_event_send_data(desc->host->sim, 10000000, desc); + time_event_send_data(desc->host->sim, desc->host->sim->current_time + 10000000, desc); return ret; } @@ -2035,6 +2039,8 @@ static b32 time_event_process(TimeEvent *event, Sim *sim) if (event->data_count == 0) { socket_queue_unref(event->data_queue); } else { + // Reschedule to future time so time can advance + event->time = sim->current_time + 10000000; consumed = false; } } @@ -2188,6 +2194,7 @@ static b32 sim_update(Sim *sim) move_host_to_last(sim, host_idx); Host *host = sim->hosts[sim->num_hosts-1]; + host_update(host); if (host_ready(host)) host->blocked = true;