Переглянути джерело

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 11 місяців тому
батько
коміт
785faf85b6
1 змінених файлів з 11 додано та 1 видалено
  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;
 }