From f70495a48646e54272783b4b709aca0396cb85f8 Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Fri, 26 Nov 2021 08:19:58 +0100 Subject: Create daemon module and use it from server Need to run setup() after forking, otherwise each TaskRunner created in setup() will dead-lock at exit as there are now two copies of each of them but not of the threads causing the destructors to lock. This made setup a little bit more complicated as it has to forward the log and status to parent process but I turned out quite nice. --- src/server.cc | 67 +++++++++++++++++++++++++++-------------------------------- 1 file changed, 31 insertions(+), 36 deletions(-) (limited to 'src/server.cc') diff --git a/src/server.cc b/src/server.cc index 7200be0..b5a1b91 100644 --- a/src/server.cc +++ b/src/server.cc @@ -2,6 +2,7 @@ #include "args.hh" #include "config.hh" +#include "daemon.hh" #include "inet.hh" #include "logger.hh" #include "looper.hh" @@ -30,24 +31,30 @@ namespace { -class Server { +class Server : public Daemon { public: - ~Server() { + Server(Option const* config_arg, Option const* log_arg, + std::function()> default_logger_factory) + : config_name_(config_arg->is_set() ? config_arg->arg() : "travel3.conf"), + log_file_(log_arg->is_set() ? std::optional(log_arg->arg()) + : std::nullopt), + default_logger_factory_(default_logger_factory) { + } + + ~Server() override { for (auto& fd : listen_) looper_->remove(fd.get()); } - bool setup(Logger* logger, Option const* config_arg, Option const* log_arg, - std::function()> default_logger_factory) { - auto config = Config::create(logger, config_arg->is_set() - ? config_arg->arg() : "travel3.conf"); + bool setup(Logger* logger) override { + auto config = Config::create(logger, config_name_); if (!config) return false; { std::filesystem::path log_file; - if (log_arg->is_set()) { - log_file = log_arg->arg(); + if (log_file_.has_value()) { + log_file = log_file_.value(); } else { log_file = config->get_path("log_file", ""); } @@ -58,7 +65,7 @@ public: if (!logger_) return false; } else { - logger_ = default_logger_factory(); + logger_ = default_logger_factory_(); } } @@ -112,7 +119,7 @@ public: return true; } - bool run() { + bool run() override { assert(logger_); assert(looper_); assert(transport_); @@ -177,6 +184,9 @@ private: assert(false); } + std::string const config_name_; + std::optional const log_file_; + std::function()> default_logger_factory_; std::shared_ptr logger_; std::shared_ptr looper_; std::shared_ptr runner_; @@ -227,36 +237,21 @@ int main(int argc, char** argv) { return EXIT_SUCCESS; } - Server server; + auto server = std::make_unique( + config_arg, log_arg, + [daemon_arg] () { + return daemon_arg->is_set() + ? Logger::create_syslog("travel3") + : Logger::create_stdio(); + }); - // Setup errors will always be logged to stdio to make them more visible. auto logger = Logger::create_stdio(); - if (!server.setup(logger.get(), config_arg, log_arg, - [daemon_arg] () { - return daemon_arg->is_set() - ? Logger::create_syslog("travel3") - : Logger::create_stdio(); - })) - return EXIT_FAILURE; + bool ret; if (daemon_arg->is_set()) { - auto pid = fork(); - if (pid == -1) { - logger->err("Failed to fork(): %s", strerror(errno)); - return EXIT_FAILURE; - } - if (pid == 0) { - // Daemon process - chdir("/"); - setpgrp(); - close(STDIN_FILENO); - close(STDOUT_FILENO); - close(STDERR_FILENO); - return server.run() ? EXIT_SUCCESS : EXIT_FAILURE; - } else { - return EXIT_SUCCESS; - } + ret = Daemon::fork_in_background(logger.get(), std::move(server)); } else { - return server.run() ? EXIT_SUCCESS : EXIT_FAILURE; + ret = Daemon::run_in_foreground(logger.get(), std::move(server)); } + return ret ? EXIT_SUCCESS : EXIT_FAILURE; } -- cgit v1.2.3-70-g09d2