summaryrefslogtreecommitdiff
path: root/src/server.cc
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@spawned.biz>2021-11-26 08:19:58 +0100
committerJoel Klinghed <the_jk@spawned.biz>2021-11-26 08:19:58 +0100
commitf70495a48646e54272783b4b709aca0396cb85f8 (patch)
tree5e63b1f57582b3f025f1008034e4b066db0c32a6 /src/server.cc
parent9c26f52e0942e3ddc8fe90fad5da871324c66f08 (diff)
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.
Diffstat (limited to 'src/server.cc')
-rw-r--r--src/server.cc67
1 files changed, 31 insertions, 36 deletions
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<std::unique_ptr<Logger>()> default_logger_factory)
+ : config_name_(config_arg->is_set() ? config_arg->arg() : "travel3.conf"),
+ log_file_(log_arg->is_set() ? std::optional<std::string>(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<std::unique_ptr<Logger>()> 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<std::string> const log_file_;
+ std::function<std::unique_ptr<Logger>()> default_logger_factory_;
std::shared_ptr<Logger> logger_;
std::shared_ptr<Looper> looper_;
std::shared_ptr<TaskRunner> runner_;
@@ -227,36 +237,21 @@ int main(int argc, char** argv) {
return EXIT_SUCCESS;
}
- Server server;
+ auto server = std::make_unique<Server>(
+ 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;
}