summaryrefslogtreecommitdiff
path: root/init/signal_handler.cpp
diff options
context:
space:
mode:
authorBertrand SIMONNET <bsimonnet@google.com>2015-12-18 11:39:59 -0800
committerBertrand SIMONNET <bsimonnet@google.com>2016-01-08 11:12:15 -0800
commitb7e03e82b89a30b09fea88eaf2a5638df1017cf6 (patch)
tree4a82e891ea154a1ac42c736e120a1b8e985c5a06 /init/signal_handler.cpp
parenta649a7df15617e1e54cc89c2f682a5e6472bf304 (diff)
init: Allows shutting down cleanly.
When ro.build.shutdown_timeout is set, init will send a SIGTERM signal to all services on reboot. The normal shutdown process will continue once all services have exited or after the shutdown timeout (ro.build.shutdown_timeout). If ro.build.shutdown_timeout is not set, we assume a 0s timeout. Bug: 26216447 Test: manual: Ask to reboot. All services exit cleanly. Change-Id: If921f6e8d87211e500ac9fa86f3e1eabe02d18cf
Diffstat (limited to 'init/signal_handler.cpp')
-rw-r--r--init/signal_handler.cpp54
1 files changed, 2 insertions, 52 deletions
diff --git a/init/signal_handler.cpp b/init/signal_handler.cpp
index e7d42cb9b..ea483d4e2 100644
--- a/init/signal_handler.cpp
+++ b/init/signal_handler.cpp
@@ -37,62 +37,12 @@
static int signal_write_fd = -1;
static int signal_read_fd = -1;
-static std::string DescribeStatus(int status) {
- if (WIFEXITED(status)) {
- return android::base::StringPrintf("exited with status %d", WEXITSTATUS(status));
- } else if (WIFSIGNALED(status)) {
- return android::base::StringPrintf("killed by signal %d", WTERMSIG(status));
- } else if (WIFSTOPPED(status)) {
- return android::base::StringPrintf("stopped by signal %d", WSTOPSIG(status));
- } else {
- return "state changed";
- }
-}
-
-static bool wait_for_one_process() {
- int status;
- pid_t pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG));
- if (pid == 0) {
- return false;
- } else if (pid == -1) {
- ERROR("waitpid failed: %s\n", strerror(errno));
- return false;
- }
-
- Service* svc = ServiceManager::GetInstance().FindServiceByPid(pid);
-
- std::string name;
- if (svc) {
- name = android::base::StringPrintf("Service '%s' (pid %d)", svc->name().c_str(), pid);
- } else {
- name = android::base::StringPrintf("Untracked pid %d", pid);
- }
-
- NOTICE("%s %s\n", name.c_str(), DescribeStatus(status).c_str());
-
- if (!svc) {
- return true;
- }
-
- if (svc->Reap()) {
- waiting_for_exec = false;
- ServiceManager::GetInstance().RemoveService(*svc);
- }
-
- return true;
-}
-
-static void reap_any_outstanding_children() {
- while (wait_for_one_process()) {
- }
-}
-
static void handle_signal() {
// Clear outstanding requests.
char buf[32];
read(signal_read_fd, buf, sizeof(buf));
- reap_any_outstanding_children();
+ ServiceManager::GetInstance().ReapAnyOutstandingChildren();
}
static void SIGCHLD_handler(int) {
@@ -119,7 +69,7 @@ void signal_handler_init() {
act.sa_flags = SA_NOCLDSTOP;
sigaction(SIGCHLD, &act, 0);
- reap_any_outstanding_children();
+ ServiceManager::GetInstance().ReapAnyOutstandingChildren();
register_epoll_handler(signal_read_fd, handle_signal);
}