~singpolyma/biboumi

8fd2746696d32262b2e6900879a9a315e56f76f2 — Florent Le Coz 9 years ago 754dd89
Reload the conf on SIGUSR1/2
3 files changed, 36 insertions(+), 8 deletions(-)

M doc/biboumi.1.md
M src/config/config.cpp
M src/main.cpp
M doc/biboumi.1.md => doc/biboumi.1.md +4 -0
@@ 57,6 57,10 @@ The configuration file uses a simple format of the form
  from 0 to 3.  0 is debug, 1 is info, 2 is warning, 3 is error.  The
  default is 0, but a more practical value for production use is 1.

The configuration can be re-read at runtime (you can for example change the
log level without having to restart biboumi) by sending SIGUSR1 or SIGUSR2
(see kill(1)) to the process.

USAGE
-----


M src/config/config.cpp => src/config/config.cpp +0 -1
@@ 56,7 56,6 @@ void Config::connect(t_config_changed_callback callback)
void Config::close()
{
  Config* self = Config::instance().get();
  self->save_to_file();
  self->values.clear();
  Config::instance().reset();
}

M src/main.cpp => src/main.cpp +32 -7
@@ 10,7 10,9 @@
#include <signal.h>

// A flag set by the SIGINT signal handler.
volatile std::atomic<bool> stop(false);
static volatile std::atomic<bool> stop(false);
// Flag set by the SIGUSR1/2 signal handler.
static volatile std::atomic<bool> reload(false);
// A flag indicating that we are wanting to exit the process. i.e: if this
// flag is set and all connections are closed, we can exit properly.
static bool exiting = false;


@@ 35,6 37,11 @@ static void sigint_handler(int, siginfo_t*, void*)
  stop = true;
}

static void sigusr_handler(int, siginfo_t*, void*)
{
  reload = true;
}

int main(int ac, char** av)
{
  if (ac > 1)


@@ 69,14 76,21 @@ int main(int ac, char** av)
  // config
  sigset_t mask;
  sigemptyset(&mask);
  struct sigaction on_sig;
  on_sig.sa_sigaction = &sigint_handler;
  on_sig.sa_mask = mask;
  struct sigaction on_sigint;
  on_sigint.sa_sigaction = &sigint_handler;
  on_sigint.sa_mask = mask;
  // we want to catch that signal only once.
  // Sending SIGINT again will "force" an exit
  on_sig.sa_flags = SA_RESETHAND;
  sigaction(SIGINT, &on_sig, nullptr);
  sigaction(SIGTERM, &on_sig, nullptr);
  on_sigint.sa_flags = SA_RESETHAND;
  sigaction(SIGINT, &on_sigint, nullptr);
  sigaction(SIGTERM, &on_sigint, nullptr);

  // Install a signal to reload the config on SIGUSR1/2
  struct sigaction on_sigusr;
  on_sigusr.sa_sigaction = &sigusr_handler;
  on_sigusr.sa_mask = mask;
  sigaction(SIGUSR1, &on_sigusr, nullptr);
  sigaction(SIGUSR2, &on_sigusr, nullptr);

  const std::chrono::milliseconds timeout(-1);
  while (p.poll(timeout) != -1 || !exiting)


@@ 91,6 105,17 @@ int main(int ac, char** av)
      stop = false;
      xmpp_component->shutdown();
    }
    if (reload)
    {
      // Closing the config will just force it to be reopened the next time
      // a configuration option is needed
      log_info("Signal received, reloading the config...");
      Config::close();
      // Destroy the logger instance, to be recreated the next time a log
      // line needs to be written
      Logger::instance().reset();
      reload = false;
    }
    // If the only existing connection is the one to the XMPP component:
    // close the XMPP stream.
    if (exiting && p.size() == 1 && xmpp_component->is_document_open())