Reload on SIGHUP

refs #5230
This commit is contained in:
Alexander A. Klimov 2019-07-15 12:11:19 +02:00
parent c303d08c24
commit 249408209d
1 changed files with 34 additions and 1 deletions

View File

@ -178,6 +178,7 @@ std::vector<String> DaemonCommand::GetArgumentSuggestions(const String& argument
#ifndef _WIN32 #ifndef _WIN32
pid_t l_UmbrellaPid = 0; pid_t l_UmbrellaPid = 0;
static std::atomic<bool> l_AllowedToWork (false);
#endif /* _WIN32 */ #endif /* _WIN32 */
static inline static inline
@ -194,6 +195,10 @@ int RunWorker(const std::vector<std::string>& configs)
#ifndef _WIN32 #ifndef _WIN32
// Notify umbrella process about the config loading success. // Notify umbrella process about the config loading success.
(void)kill(l_UmbrellaPid, SIGUSR2); (void)kill(l_UmbrellaPid, SIGUSR2);
while (!l_AllowedToWork.load()) {
Utility::Sleep(0.2);
}
#endif /* _WIN32 */ #endif /* _WIN32 */
/* restore the previous program state */ /* restore the previous program state */
@ -248,6 +253,7 @@ static const sigset_t l_UnixWorkerSignals = ([]() -> sigset_t {
(void)sigaddset(&s, SIGUSR2); (void)sigaddset(&s, SIGUSR2);
(void)sigaddset(&s, SIGINT); (void)sigaddset(&s, SIGINT);
(void)sigaddset(&s, SIGTERM); (void)sigaddset(&s, SIGTERM);
(void)sigaddset(&s, SIGHUP);
return s; return s;
})(); })();
@ -255,6 +261,7 @@ static const sigset_t l_UnixWorkerSignals = ([]() -> sigset_t {
static std::atomic<pid_t> l_CurrentlyStartingUnixWorkerPid (-1); static std::atomic<pid_t> l_CurrentlyStartingUnixWorkerPid (-1);
static std::atomic<UnixWorkerState> l_CurrentlyStartingUnixWorkerState (UnixWorkerState::Pending); static std::atomic<UnixWorkerState> l_CurrentlyStartingUnixWorkerState (UnixWorkerState::Pending);
static std::atomic<int> l_TermSignal (-1); static std::atomic<int> l_TermSignal (-1);
static std::atomic<bool> l_RequestedReload (false);
static void UmbrellaSignalHandler(int num, siginfo_t *info, void*) static void UmbrellaSignalHandler(int num, siginfo_t *info, void*)
{ {
@ -283,12 +290,20 @@ static void UmbrellaSignalHandler(int num, siginfo_t *info, void*)
} }
l_TermSignal.store(num); l_TermSignal.store(num);
break;
case SIGHUP:
l_RequestedReload.store(true);
} }
} }
static void WorkerSignalHandler(int num, siginfo_t *info, void*) static void WorkerSignalHandler(int num, siginfo_t *info, void*)
{ {
switch (num) { switch (num) {
case SIGUSR2:
if (info->si_pid == l_UmbrellaPid) {
l_AllowedToWork.store(true);
}
break;
case SIGINT: case SIGINT:
case SIGTERM: case SIGTERM:
if (info->si_pid == l_UmbrellaPid) { if (info->si_pid == l_UmbrellaPid) {
@ -326,7 +341,7 @@ static pid_t StartUnixWorker(const std::vector<std::string>& configs)
sa.sa_handler = SIG_DFL; sa.sa_handler = SIG_DFL;
(void)sigaction(SIGCHLD, &sa, nullptr); (void)sigaction(SIGCHLD, &sa, nullptr);
(void)sigaction(SIGUSR2, &sa, nullptr); (void)sigaction(SIGHUP, &sa, nullptr);
} }
{ {
@ -336,6 +351,7 @@ static pid_t StartUnixWorker(const std::vector<std::string>& configs)
sa.sa_sigaction = &WorkerSignalHandler; sa.sa_sigaction = &WorkerSignalHandler;
sa.sa_flags = SA_RESTART | SA_SIGINFO; sa.sa_flags = SA_RESTART | SA_SIGINFO;
(void)sigaction(SIGUSR2, &sa, nullptr);
(void)sigaction(SIGINT, &sa, nullptr); (void)sigaction(SIGINT, &sa, nullptr);
(void)sigaction(SIGTERM, &sa, nullptr); (void)sigaction(SIGTERM, &sa, nullptr);
} }
@ -473,6 +489,7 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vector<std::strin
(void)sigaction(SIGUSR2, &sa, nullptr); (void)sigaction(SIGUSR2, &sa, nullptr);
(void)sigaction(SIGINT, &sa, nullptr); (void)sigaction(SIGINT, &sa, nullptr);
(void)sigaction(SIGTERM, &sa, nullptr); (void)sigaction(SIGTERM, &sa, nullptr);
(void)sigaction(SIGHUP, &sa, nullptr);
} }
pid_t currentWorker = StartUnixWorker(configs); pid_t currentWorker = StartUnixWorker(configs);
@ -481,6 +498,8 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vector<std::strin
return EXIT_FAILURE; return EXIT_FAILURE;
} }
(void)kill(currentWorker, SIGUSR2);
bool requestedTermination = false; bool requestedTermination = false;
for (;;) { for (;;) {
@ -492,6 +511,20 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vector<std::strin
} }
} }
if (l_RequestedReload.exchange(false)) {
pid_t nextWorker = StartUnixWorker(configs);
if (nextWorker != -1) {
(void)kill(currentWorker, SIGTERM);
while (waitpid(currentWorker, nullptr, 0) == -1 && errno == EINTR) {
}
(void)kill(nextWorker, SIGUSR2);
currentWorker = nextWorker;
}
}
{ {
int status; int status;
if (waitpid(currentWorker, &status, WNOHANG) > 0) { if (waitpid(currentWorker, &status, WNOHANG) > 0) {