[Fix] Implement destructors preventing memleaks.

Fixes a bunch of memleaks related to the new Machine and VFS
architecture.

The Machine and vfs_node objects were created with 'new' but were never
properly destroyed, leading to memleaks during CoW operations and on
server shutdown.

- Added a recursive 'delete_vfs_tree' function
- Machine destructor calls this function to lean up its VFS
- CommandProcessor correctly deletes old Machine objects after a CoW
- Player destructor cleans up the player's home machine.
- NetworkManager destructor cleans up all world machines.
This commit is contained in:
Ritchie Cunningham 2025-09-27 22:18:13 +01:00
parent e06d6eec37
commit c052cf3cbf
7 changed files with 38 additions and 2 deletions

View File

@ -113,8 +113,10 @@ void CommandProcessor::ensure_vfs_is_writable(void) {
new_machine->services = _home_machine->services;
new_machine->is_vfs_a_copy = true;
Machine* old_machine = _home_machine;
_home_machine = new_machine;
set_session_machine(new_machine);
delete old_machine;
_current_dir = find_node_by_path(_session_machine->vfs_root, original_path);
if(!_current_dir) { _current_dir = _session_machine->vfs_root; }
} else {
@ -139,8 +141,10 @@ void CommandProcessor::ensure_vfs_is_writable(void) {
new_machine->services = _session_machine->services;
new_machine->is_vfs_a_copy = true;
Machine* old_machine = _world_machines[remote_ip];
_world_machines[remote_ip] = new_machine;
set_session_machine(new_machine);
delete old_machine;
_current_dir = find_node_by_path(_session_machine->vfs_root, original_path);
if(!_current_dir) { _current_dir = _session_machine->vfs_root; }

6
common/src/machine.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "machine.h"
#include "vfs.h"
Machine::~Machine(void) {
delete_vfs_tree(vfs_root);
}

View File

@ -55,7 +55,7 @@ MachineManager::MachineManager(void) {
}
MachineManager::~MachineManager(void) {
/* TODO: Implement recursive deletion of all created VFS nodes.*/
delete_vfs_tree(_vfs_template_root);
}
Machine* MachineManager::create_machine(uint32_t id, const std::string& hostname,

View File

@ -9,3 +9,16 @@ std::string get_full_path(vfs_node* node) {
}
return get_full_path(node->parent) + "/" + node->name;
}
void delete_vfs_tree(vfs_node* node) {
if(!node) {
return;
}
if(node->type == DIR_NODE) {
for(auto const& [key, val] : node->children) {
delete_vfs_tree(val);
}
}
delete node;
}

View File

@ -26,3 +26,4 @@ struct vfs_node {
};
std::string get_full_path(vfs_node* node);
void delete_vfs_tree(vfs_node* node);

View File

@ -26,7 +26,12 @@ NetworkManager::NetworkManager(void) : _acceptor(_io_context) {
fprintf(stderr, "Created world with %zu networks\n", _world_machines.size());
}
NetworkManager::~NetworkManager(void) { stop(); }
NetworkManager::~NetworkManager(void) {
for(auto const& [ip, machine] : _world_machines) {
delete machine;
}
stop();
}
void NetworkManager::stop(void) {
_io_context.stop();

View File

@ -5,11 +5,18 @@
Player::Player(uint32_t new_id, Machine* home_machine,
std::map<std::string, Machine*>& world_machines) :
id(new_id) {
cmd_processor = new CommandProcessor(home_machine, world_machines);
}
Player::~Player(void) {
if(cmd_processor) {
/*
* Player is owner of their own machine. CommandProcessor
* holds the most current pointer to it (in case of CoW).
* Delete the machine first, then the processor point to it.
*/
delete cmd_processor->get_home_machine();
delete cmd_processor;
}
}