Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb3fa921 authored by Tom Cherry's avatar Tom Cherry Committed by Gerrit Code Review
Browse files

Merge "init: fix process restarting"

parents c7ba2bb5 d269e3a7
Loading
Loading
Loading
Loading
+25 −12
Original line number Diff line number Diff line
@@ -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) {
@@ -1175,13 +1184,17 @@ int main(int argc, char** argv) {
            am.ExecuteOneCommand();
        }
        if (!(waiting_for_prop || sm.IsWaitingForExec())) {
            if (!shutting_down) restart_processes();
            if (!shutting_down) {
                auto next_process_restart_time = RestartProcesses();

                // 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 (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.
            if (am.HasMoreCommands()) epoll_timeout_ms = 0;
+0 −25
Original line number Diff line number Diff line
@@ -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) {
+1 −3
Original line number Diff line number Diff line
@@ -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;