Home | History | Annotate | Download | only in daemons
      1 // Copyright 2014 The Chromium OS Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <brillo/daemons/daemon.h>
      6 
      7 #include <sysexits.h>
      8 
      9 #include <base/bind.h>
     10 #include <base/files/file_path.h>
     11 #include <base/files/file_util.h>
     12 #include <base/logging.h>
     13 #include <base/run_loop.h>
     14 
     15 namespace brillo {
     16 
     17 Daemon::Daemon() : exit_code_{EX_OK} {
     18   message_loop_.SetAsCurrent();
     19 }
     20 
     21 Daemon::~Daemon() {
     22 }
     23 
     24 int Daemon::Run() {
     25   int exit_code = OnInit();
     26   if (exit_code != EX_OK)
     27     return exit_code;
     28 
     29   message_loop_.Run();
     30 
     31   OnShutdown(&exit_code_);
     32 
     33   // base::RunLoop::QuitClosure() causes the message loop to quit
     34   // immediately, even if pending tasks are still queued.
     35   // Run a secondary loop to make sure all those are processed.
     36   // This becomes important when working with D-Bus since dbus::Bus does
     37   // a bunch of clean-up tasks asynchronously when shutting down.
     38   while (message_loop_.RunOnce(false /* may_block */)) {}
     39 
     40   return exit_code_;
     41 }
     42 
     43 void Daemon::Quit() { QuitWithExitCode(EX_OK); }
     44 
     45 void Daemon::QuitWithExitCode(int exit_code) {
     46   exit_code_ = exit_code;
     47   message_loop_.PostTask(FROM_HERE, QuitClosure());
     48 }
     49 
     50 void Daemon::RegisterHandler(
     51     int signal,
     52     const AsynchronousSignalHandlerInterface::SignalHandler& callback) {
     53   async_signal_handler_.RegisterHandler(signal, callback);
     54 }
     55 
     56 void Daemon::UnregisterHandler(int signal) {
     57   async_signal_handler_.UnregisterHandler(signal);
     58 }
     59 
     60 int Daemon::OnInit() {
     61   async_signal_handler_.Init();
     62   for (int signal : {SIGTERM, SIGINT}) {
     63     async_signal_handler_.RegisterHandler(
     64         signal, base::Bind(&Daemon::Shutdown, base::Unretained(this)));
     65   }
     66   async_signal_handler_.RegisterHandler(
     67       SIGHUP, base::Bind(&Daemon::Restart, base::Unretained(this)));
     68   return EX_OK;
     69 }
     70 
     71 void Daemon::OnShutdown(int* /* exit_code */) {
     72   // Do nothing.
     73 }
     74 
     75 bool Daemon::OnRestart() {
     76   // Not handled.
     77   return false;  // Returning false will shut down the daemon instead.
     78 }
     79 
     80 bool Daemon::Shutdown(const signalfd_siginfo& /* info */) {
     81   Quit();
     82   return true;  // Unregister the signal handler.
     83 }
     84 
     85 bool Daemon::Restart(const signalfd_siginfo& /* info */) {
     86   if (OnRestart())
     87     return false;  // Keep listening to the signal.
     88   Quit();
     89   return true;  // Unregister the signal handler.
     90 }
     91 
     92 }  // namespace brillo
     93