summaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
authorTom Cherry <tomcherry@google.com>2017-08-01 17:04:44 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-08-01 17:04:44 +0000
commit25422816d4acad3c4e4d7cae5eb44c1525ed896d (patch)
treec1ffd77c3140292e7575a8fdeea82f8651f37649 /init
parent1cb98847d58decba5fc021d69a1df70bfb0913eb (diff)
parenteb3fa921916f2505d85fe42b780a890f7358f482 (diff)
downloadcore-25422816d4acad3c4e4d7cae5eb44c1525ed896d.tar.gz
core-25422816d4acad3c4e4d7cae5eb44c1525ed896d.tar.bz2
core-25422816d4acad3c4e4d7cae5eb44c1525ed896d.zip
Merge "init: fix process restarting"
am: eb3fa92191 Change-Id: Ic03cf607631c49c1d37584f7641d9300a79f5457
Diffstat (limited to 'init')
-rw-r--r--init/init.cpp37
-rw-r--r--init/service.cpp25
-rw-r--r--init/service.h4
3 files changed, 26 insertions, 40 deletions
diff --git a/init/init.cpp b/init/init.cpp
index c51217e9b..58410982e 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -53,6 +53,7 @@
#include <fstream>
#include <memory>
+#include <optional>
#include <vector>
#include "bootchart.h"
@@ -84,7 +85,6 @@ static int property_triggers_enabled = 0;
static char qemu[32];
std::string default_console = "/dev/console";
-static time_t process_needs_restart_at;
const char *ENV[32];
@@ -219,12 +219,21 @@ void property_changed(const std::string& name, const std::string& value) {
}
}
-static void restart_processes()
-{
- process_needs_restart_at = 0;
- ServiceManager::GetInstance().ForEachServiceWithFlags(SVC_RESTARTING, [](Service* s) {
- s->RestartIfNeeded(&process_needs_restart_at);
+static std::optional<boot_clock::time_point> RestartProcesses() {
+ std::optional<boot_clock::time_point> next_process_restart_time;
+ ServiceManager::GetInstance().ForEachService([&next_process_restart_time](Service* s) {
+ if (!(s->flags() & SVC_RESTARTING)) return;
+
+ auto restart_time = s->time_started() + 5s;
+ if (boot_clock::now() > restart_time) {
+ s->Start();
+ } else {
+ if (!next_process_restart_time || restart_time < *next_process_restart_time) {
+ next_process_restart_time = restart_time;
+ }
+ }
});
+ return next_process_restart_time;
}
void handle_control_message(const std::string& msg, const std::string& name) {
@@ -1206,12 +1215,16 @@ int main(int argc, char** argv) {
am.ExecuteOneCommand();
}
if (!(waiting_for_prop || sm.IsWaitingForExec())) {
- if (!shutting_down) restart_processes();
-
- // If there's a process that needs restarting, wake up in time for that.
- if (process_needs_restart_at != 0) {
- epoll_timeout_ms = (process_needs_restart_at - time(nullptr)) * 1000;
- if (epoll_timeout_ms < 0) epoll_timeout_ms = 0;
+ if (!shutting_down) {
+ auto next_process_restart_time = RestartProcesses();
+
+ // If there's a process that needs restarting, wake up in time for that.
+ if (next_process_restart_time) {
+ epoll_timeout_ms = std::chrono::ceil<std::chrono::milliseconds>(
+ *next_process_restart_time - boot_clock::now())
+ .count();
+ if (epoll_timeout_ms < 0) epoll_timeout_ms = 0;
+ }
}
// If there's more work to do, wake up again immediately.
diff --git a/init/service.cpp b/init/service.cpp
index d0a0751cf..d72433afa 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -890,22 +890,6 @@ void Service::Restart() {
} /* else: Service is restarting anyways. */
}
-void Service::RestartIfNeeded(time_t* process_needs_restart_at) {
- boot_clock::time_point now = boot_clock::now();
- boot_clock::time_point next_start = time_started_ + 5s;
- if (now > next_start) {
- flags_ &= (~SVC_RESTARTING);
- Start();
- return;
- }
-
- time_t next_start_time_t = time(nullptr) +
- time_t(std::chrono::duration_cast<std::chrono::seconds>(next_start - now).count());
- if (next_start_time_t < *process_needs_restart_at || *process_needs_restart_at == 0) {
- *process_needs_restart_at = next_start_time_t;
- }
-}
-
// The how field should be either SVC_DISABLED, SVC_RESET, or SVC_RESTART.
void Service::StopOrReset(int how) {
// The service is still SVC_RUNNING until its process exits, but if it has
@@ -1123,15 +1107,6 @@ void ServiceManager::ForEachServiceInClass(const std::string& classname,
}
}
-void ServiceManager::ForEachServiceWithFlags(unsigned matchflags,
- void (*func)(Service* svc)) const {
- for (const auto& s : services_) {
- if (s->flags() & matchflags) {
- func(s.get());
- }
- }
-}
-
void ServiceManager::RemoveService(const Service& svc) {
auto svc_it = std::find_if(services_.begin(), services_.end(),
[&svc] (const std::unique_ptr<Service>& s) {
diff --git a/init/service.h b/init/service.h
index 976f431e0..850aca487 100644
--- a/init/service.h
+++ b/init/service.h
@@ -83,7 +83,6 @@ class Service {
void Stop();
void Terminate();
void Restart();
- void RestartIfNeeded(time_t* process_needs_restart_at);
void Reap();
void DumpState() const;
void SetShutdownCritical() { flags_ |= SVC_SHUTDOWN_CRITICAL; }
@@ -94,6 +93,7 @@ class Service {
const std::set<std::string>& classnames() const { return classnames_; }
unsigned flags() const { return flags_; }
pid_t pid() const { return pid_; }
+ android::base::boot_clock::time_point time_started() const { return time_started_; }
int crash_count() const { return crash_count_; }
uid_t uid() const { return uid_; }
gid_t gid() const { return gid_; }
@@ -217,8 +217,6 @@ class ServiceManager {
void ForEachServiceShutdownOrder(const std::function<void(Service*)>& callback) const;
void ForEachServiceInClass(const std::string& classname,
void (*func)(Service* svc)) const;
- void ForEachServiceWithFlags(unsigned matchflags,
- void (*func)(Service* svc)) const;
void ReapAnyOutstandingChildren();
void RemoveService(const Service& svc);
void DumpState() const;