Browse Source

Break holds from soft dependents if a service is manually stopped.

If all dependents are soft (waits-for or soft) then break their holds on
a service that is manually stopped. This prevents the service from
immediately re-starting, which would be unexpected behaviour.
Davin McCall 4 years ago
parent
commit
7cbd73c805
1 changed files with 20 additions and 0 deletions
  1. 20 0
      src/service.cc

+ 20 - 0
src/service.cc

@@ -457,6 +457,26 @@ void service_record::stop(bool bring_down) noexcept
         release();
     }
 
+    // If it's a manual bring-down, we'll also break holds from waits-for dependencies, to avoid
+    // bouncing back up again -- but only if all holds are from waits-for dependencies.
+    if (bring_down) {
+        if (std::all_of(dependents.begin(), dependents.end(), [](service_dep * x) {
+            return x->dep_type == dependency_type::WAITS_FOR || x->dep_type == dependency_type::SOFT; }))
+        {
+            for (auto dept : dependents) {
+                if (dept->waiting_on) {
+                    dept->waiting_on = false;
+                    dept->get_from()->dependency_started();
+                }
+                if (dept->holding_acq) {
+                    dept->holding_acq = false;
+                    // release without issuing stop, since we issue stop if necessary below
+                    release(false);
+                }
+            }
+        }
+    }
+
     if (bring_down && service_state != service_state_t::STOPPED
     		&& service_state != service_state_t::STOPPING) {
     	stop_reason = stopped_reason_t::NORMAL;