Browse Source

Fix: before/after ordering could sometimes be skipped

If service A was ordered "before" service B, and they were both started
at the same time but dependency checks for B happened to run first, B's
checks would be satisfied (A is not yet starting so the ordering has no
effect). Fix it by checking dependents in the start check and setting
waiting_on in any relevant dependency links.
Davin McCall 10 months ago
parent
commit
785faf85b6
1 changed files with 11 additions and 1 deletions
  1. 11 1
      src/service.cc

+ 11 - 1
src/service.cc

@@ -242,7 +242,7 @@ void service_record::initiate_start() noexcept
     waiting_for_deps = true;
 
     if (start_check_dependencies()) {
-        waiting_for_deps = false;
+        // Note: we can't set waiting_for_deps false here since ordering dependencies might still kick in
         services->add_transition_queue(this);
     }
 }
@@ -314,6 +314,7 @@ void service_record::execute_transition() noexcept
 {
     if (service_state == service_state_t::STARTING) {
         if (check_deps_started()) {
+            waiting_for_deps = false;
             all_deps_started();
         }
     }
@@ -410,6 +411,15 @@ bool service_record::start_check_dependencies() noexcept
         }
     }
 
+    for (auto * dept : dependents) {
+        if (!dept->waiting_on && dept->is_only_ordering()) {
+            service_record *from = dept->get_from();
+            if (from->get_state() == service_state_t::STARTING) {
+                dept->waiting_on = true;
+            }
+        }
+    }
+
     return all_deps_started;
 }