Use restart timer also for non-smooth-recovery restarts.
authorDavin McCall <davmac@davmac.org>
Fri, 2 Jun 2017 18:13:46 +0000 (19:13 +0100)
committerDavin McCall <davmac@davmac.org>
Fri, 2 Jun 2017 18:13:46 +0000 (19:13 +0100)
src/service.cc
src/service.h

index 69e8cbc5447f8649cdfa511b080fd6c68b114dfa..282809ca5a0efe39805e2936611cacdfefde95a5 100644 (file)
@@ -91,7 +91,6 @@ void ServiceRecord::stopped() noexcept
         }
     }
 
-    will_restart &= (desired_state == ServiceState::STARTED);
     for (auto dependency : depends_on) {
         // we signal dependencies in case they are waiting for us to stop - but only if we won't
         // restart or if they are stopping uninterruptibly.
@@ -104,6 +103,7 @@ void ServiceRecord::stopped() noexcept
 
     if (will_restart) {
         // Desired state is "started".
+        restarting = true;
         service_set->addToStartQueue(this);
     }
     else {
@@ -763,8 +763,13 @@ bool ServiceRecord::start_ps_process() noexcept
 
 bool base_process_service::start_ps_process() noexcept
 {
-    eventLoop.get_time(last_start_time, clock_type::MONOTONIC);
-    return start_ps_process(exec_arg_parts, onstart_flags.runs_on_console);
+    if (restarting) {
+        restart_ps_process();
+        return true;
+    }
+    else {
+        return start_ps_process(exec_arg_parts, onstart_flags.runs_on_console);
+    }
 }
 
 bool base_process_service::start_ps_process(const std::vector<const char *> &cmd, bool on_console) noexcept
@@ -774,6 +779,8 @@ bool base_process_service::start_ps_process(const std::vector<const char *> &cmd
     // exec closes the pipe, and the parent sees EOF. If the exec is unsuccessful, the errno
     // is written to the pipe, and the parent can read it.
 
+    eventLoop.get_time(last_start_time, clock_type::MONOTONIC);
+
     int pipefd[2];
     if (pipe2(pipefd, O_CLOEXEC)) {
         log(LogLevel::ERROR, service_name, ": can't create status check pipe: ", strerror(errno));
@@ -1193,7 +1200,10 @@ void base_process_service::restart_ps_process() noexcept
 
     if (tdiff_s > 0 || tdiff_ns > 200000000) {
         // > 200ms
-        start_ps_process();
+        restarting = false;
+        if (! start_ps_process(exec_arg_parts, onstart_flags.runs_on_console)) {
+            // TODO handle appropriately; mark service stopped.
+        }
     }
     else {
         timespec timeout;
@@ -1211,6 +1221,8 @@ dasynq::rearm process_restart_timer::timer_expiry(EventLoop_t &, int expiry_coun
 dasynq::rearm base_process_service::restart_timer_expired() noexcept
 {
     // begin starting process:
-    start_ps_process();
+    if (! start_ps_process(exec_arg_parts, onstart_flags.runs_on_console)) {
+        // TODO handle appropriately; mark service stopped.
+    }
     return dasynq::rearm::DISARM;
 }
index 671de17bc04da9569543f3ef546c42950b1c176e..e4dd2d9967a6356cdf1d663194bd0488aff7ebda 100644 (file)
@@ -243,6 +243,7 @@ class ServiceRecord
     bool prop_require : 1;      // require must be propagated
     bool prop_release : 1;      // release must be propagated
     bool prop_failure : 1;      // failure to start must be propagated
+    bool restarting : 1;        // re-starting after unexpected termination
     
     int required_by = 0;        // number of dependents wanting this service to be started
 
@@ -397,7 +398,7 @@ class ServiceRecord
             pinned_stopped(false), pinned_started(false), waiting_for_deps(false),
             waiting_for_execstat(false), start_explicit(false),
             prop_require(false), prop_release(false), prop_failure(false),
-            force_stop(false)
+            restarting(false), force_stop(false)
     {
         service_set = set;
         service_name = name;