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 brillo_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 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 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