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 15namespace brillo { 16 17Daemon::Daemon() : exit_code_{EX_OK} { 18 brillo_message_loop_.SetAsCurrent(); 19} 20 21Daemon::~Daemon() { 22} 23 24int Daemon::Run() { 25 int exit_code = OnInit(); 26 if (exit_code != EX_OK) 27 return exit_code; 28 29 brillo_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 (brillo_message_loop_.RunOnce(false /* may_block */)) {} 39 40 return exit_code_; 41} 42 43void Daemon::Quit() { QuitWithExitCode(EX_OK); } 44 45void Daemon::QuitWithExitCode(int exit_code) { 46 exit_code_ = exit_code; 47 message_loop_.PostTask(FROM_HERE, QuitClosure()); 48} 49 50void Daemon::RegisterHandler( 51 int signal, 52 const AsynchronousSignalHandlerInterface::SignalHandler& callback) { 53 async_signal_handler_.RegisterHandler(signal, callback); 54} 55 56void Daemon::UnregisterHandler(int signal) { 57 async_signal_handler_.UnregisterHandler(signal); 58} 59 60int 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 71void Daemon::OnShutdown(int* /* exit_code */) { 72 // Do nothing. 73} 74 75bool Daemon::OnRestart() { 76 // Not handled. 77 return false; // Returning false will shut down the daemon instead. 78} 79 80bool Daemon::Shutdown(const signalfd_siginfo& /* info */) { 81 Quit(); 82 return true; // Unregister the signal handler. 83} 84 85bool 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