From a428f3e3135795575f0dd1114f94272b87c240e3 Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Tue, 19 Mar 2019 23:53:09 +0100 Subject: [PATCH] Reinitialize logger after fork() --- src/logger.hpp | 4 ++++ src/urd.cpp | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/logger.hpp b/src/logger.hpp index 3b10bdf..9b34d5a 100644 --- a/src/logger.hpp +++ b/src/logger.hpp @@ -131,6 +131,10 @@ public: return global_logger(); } + static inline void destroy_global_logger() { + global_logger().reset(); + } + // some macros to make it more convenient to use the global logger #define LOGGER_INFO(...) \ do { \ diff --git a/src/urd.cpp b/src/urd.cpp index 2a3f362..b407795 100644 --- a/src/urd.cpp +++ b/src/urd.cpp @@ -94,8 +94,23 @@ pid_t urd::daemonize() { return 0; } + // We need to destroy the global logger before calling fork. Otherwise the + // logger will not function properly since its internal thread will not + // be duplicated by fork(). Furthermore, if we don't destroy pre-fork() + // and attempt to replace it post-fork(), the logger destructor will attempt + // to join the (now invalid) thread and end up blocking forever. To avoid + // this (and since we want to be able to output messages from all + // processes), we destroy it now and recreate it post-fork() both in the + // parent process and in the child. + logger::destroy_global_logger(); + /* Fork off the parent process */ - if((pid = fork()) < 0) { + pid = fork(); + + // re-initialize logging facilities (post-fork) + init_logger(); + + if(pid < 0) { LOGGER_ERRNO("Failed to create child process"); exit(EXIT_FAILURE); } @@ -1536,7 +1551,7 @@ urd_error urd::check_shutdown() { int urd::run() { - // initialize logging facilities + // initialize logging facilities (pre-fork) init_logger(); // validate settings -- GitLab