From 5f4f4e0ce6e92ed962b851fa514f3d56ddfce801 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 25 May 2025 11:53:07 +1200 Subject: [PATCH] fix signal handling --- src/main.cpp | 102 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 91 insertions(+), 11 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index cbdce15..a0c3a87 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,37 +3,117 @@ #include #include #include +#include +#include +#include +#include namespace simple_object_storage { -int main(int argc, char* argv[]) { +std::atomic g_running{true}; +std::unique_ptr g_server; +std::thread g_server_thread; +std::filesystem::path get_config_path() { std::filesystem::path system_config_path = "/data/sos_config.json"; std::filesystem::path user_config_path = std::filesystem::path(std::getenv("HOME")) / ".config/simple_object_storage/config.json"; - std::filesystem::path config_path; - if (std::filesystem::exists(system_config_path)) config_path = system_config_path; - else if (std::filesystem::exists(user_config_path)) config_path = user_config_path; - else { - std::cout << "No config file found. Checked " << system_config_path << " and " << user_config_path << std::endl; - return 1; + if (std::filesystem::exists(system_config_path)) return system_config_path; + if (std::filesystem::exists(user_config_path)) return user_config_path; + + std::cout << "No config file found. Checked " << system_config_path << " and " << user_config_path << std::endl; + return std::filesystem::path(); +} + +bool initialize_server() { + std::filesystem::path config_path = get_config_path(); + if (config_path.empty()) { + return false; } ServerConfig config; if (!simple_object_storage::load_config(config_path, config)) { std::cout << "Config file at " << config_path << " is not valid." << std::endl; - return 1; + return false; } std::cout << "Starting server at " << config.host << ":" << config.port << std::endl; std::cout << "Object store path: " << config.object_store_path << std::endl; - Server server(config); - if (!server.start()) { - std::cerr << "Failed to start server" << std::endl; + g_server = std::make_unique(config); + + // Start server in a separate thread + g_server_thread = std::thread([&]() { + if (!g_server->start()) { + std::cerr << "Failed to start server" << std::endl; + g_running = false; + } + }); + + return true; +} + +void stop_server() { + if (g_server) { + std::cout << "Stopping server..." << std::endl; + g_server->stop(); + if (g_server_thread.joinable()) { + g_server_thread.join(); + } + g_server.reset(); + } +} + +void signal_handler(int signal) { + switch (signal) { + case SIGHUP: + std::cout << "Received SIGHUP signal - reloading configuration" << std::endl; + stop_server(); + if (!initialize_server()) { + std::cerr << "Failed to restart server with new configuration" << std::endl; + g_running = false; + } + break; + case SIGTERM: + case SIGINT: + std::cout << "Received termination signal" << std::endl; + g_running = false; + break; + } +} + +int main(int argc, char* argv[]) { + // Set up signal handlers + struct sigaction sa; + sa.sa_handler = signal_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + + if (sigaction(SIGHUP, &sa, nullptr) == -1) { + std::cerr << "Failed to set up SIGHUP handler" << std::endl; + return 1; + } + if (sigaction(SIGTERM, &sa, nullptr) == -1) { + std::cerr << "Failed to set up SIGTERM handler" << std::endl; + return 1; + } + if (sigaction(SIGINT, &sa, nullptr) == -1) { + std::cerr << "Failed to set up SIGINT handler" << std::endl; return 1; } + // Initial server startup + if (!initialize_server()) { + return 1; + } + + // Main loop - wait for signals + while (g_running) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + // Graceful shutdown + stop_server(); return 0; }