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.
This commit is contained in:
Claude
2026-01-23 20:26:52 +00:00
parent 30c60d84df
commit 6a3987d418
+12 -5
View File
@@ -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;