diff --git a/quakey/src/quakey.c b/quakey/src/quakey.c index 4f1905a..997d922 100644 --- a/quakey/src/quakey.c +++ b/quakey/src/quakey.c @@ -369,6 +369,7 @@ static void time_event_wakeup(Sim *sim, Nanos time, Host *host); static void time_event_connect(Sim *sim, Nanos time, Desc *desc); static void time_event_disconnect(Sim *sim, Nanos time, Desc *desc, b32 rst); static void time_event_send_data(Sim *sim, Nanos time, Desc *desc); +static void remove_events_targeting_desc(Sim *sim, Desc *desc); ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// @@ -776,7 +777,7 @@ static bool accept_queue_empty(AcceptQueue *queue) // If the descriptor is a connection socket and rst=true, // the peer connection will be marked as "reset" instead // of simply closed. -static void desc_free(Desc *desc, bool rst) +static void desc_free(Sim *sim, Desc *desc, bool rst) { switch (desc->type) { case DESC_EMPTY: @@ -793,6 +794,9 @@ static void desc_free(Desc *desc, bool rst) accept_queue_free(&desc->accept_queue); break; case DESC_SOCKET_C: + // Remove any pending events targeting this descriptor before freeing it + if (sim) + remove_events_targeting_desc(sim, desc); if (desc->peer) { // A connection was previously established. // We need to update the other end of the connection. @@ -989,7 +993,7 @@ static void host_free(Host *host) for (int i = 0; i < HOST_DESC_LIMIT; i++) { if (host->desc[i].type != DESC_EMPTY) - desc_free(&host->desc[i], true); + desc_free(host->sim, &host->desc[i], true); } free(host->state); @@ -1285,7 +1289,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, host->sim->current_time + 10000000, &host->desc[desc_idx], false); - desc_free(&host->desc[desc_idx], false); + desc_free(host->sim, &host->desc[desc_idx], false); host->num_desc--; return 0; } @@ -1934,6 +1938,26 @@ static b32 remove_connect_event(Sim *sim, Desc *desc) return true; } +// Remove all events that target a specific descriptor (DISCONNECT and DATA events) +static void remove_events_targeting_desc(Sim *sim, Desc *desc) +{ + int i = 0; + while (i < sim->num_events) { + TimeEvent *event = &sim->events[i]; + if (event->dst_desc == desc) { + // Free any resources associated with the event + if (event->type == EVENT_TYPE_DATA && event->data_queue) { + socket_queue_unref(event->data_queue); + } + // Remove by swapping with last element + sim->events[i] = sim->events[--sim->num_events]; + // Don't increment i - need to check the swapped element + } else { + i++; + } + } +} + static void time_event_disconnect(Sim *sim, Nanos time, Desc *desc, b32 rst) { if (remove_connect_event(sim, desc)) diff --git a/src/main.c b/src/main.c index 65a92c9..7b199a2 100644 --- a/src/main.c +++ b/src/main.c @@ -160,10 +160,10 @@ int main(void) quakey_spawn(quakey, config, "ms --addr 127.0.0.3 --port 8080"); } - // Chunk Server + // Chunk Server 1 { QuakeySpawn config = { - .name = "cs", + .name = "cs1", .state_size = sizeof(ChunkServer), .init_func = chunk_server_init, .tick_func = chunk_server_tick, @@ -176,6 +176,38 @@ int main(void) quakey_spawn(quakey, config, "cs --addr 127.0.0.4 --port 8081 --remote-addr 127.0.0.3 --remote-port 8080"); } + // Chunk Server 2 + { + QuakeySpawn config = { + .name = "cs2", + .state_size = sizeof(ChunkServer), + .init_func = chunk_server_init, + .tick_func = chunk_server_tick, + .free_func = chunk_server_free, + .addrs = (char*[]) { "127.0.0.5" }, + .num_addrs = 1, + .disk_size = 10<<20, + .platform = QUAKEY_LINUX, + }; + quakey_spawn(quakey, config, "cs --addr 127.0.0.5 --port 8082 --remote-addr 127.0.0.3 --remote-port 8080"); + } + + // Chunk Server 3 + { + QuakeySpawn config = { + .name = "cs3", + .state_size = sizeof(ChunkServer), + .init_func = chunk_server_init, + .tick_func = chunk_server_tick, + .free_func = chunk_server_free, + .addrs = (char*[]) { "127.0.0.6" }, + .num_addrs = 1, + .disk_size = 10<<20, + .platform = QUAKEY_LINUX, + }; + quakey_spawn(quakey, config, "cs --addr 127.0.0.6 --port 8083 --remote-addr 127.0.0.3 --remote-port 8080"); + } + while (simulation_running) quakey_schedule_one(quakey);