From b96f0fa2dfd35dee8a541266bfcb404e492bbdcd Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Thu, 7 Jun 2018 18:22:08 +0200 Subject: [PATCH] init: defer immediate restart of abandoned child While a child is abandoned, we must limit the start of anothers with the same name. Otherwise - of the child has startup problems - a number of abandoned children with the same name may queue up. This becomes a problem whenever the child destruction depends on an asynchronous service that provides an env session for the children. If the service is unable to keep up with the session requests (both create and close), the queue of abandoned children becomes unbounded. Limiting the child creation rate to one abandoned child per name mitigates this problem. --- repos/os/src/init/main.cc | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/repos/os/src/init/main.cc b/repos/os/src/init/main.cc index 5b4a142a0c..3868303a63 100644 --- a/repos/os/src/init/main.cc +++ b/repos/os/src/init/main.cc @@ -356,15 +356,26 @@ void Init::Main::_handle_config() try { _config_xml.for_each_sub_node("start", [&] (Xml_node start_node) { - /* skip start node if corresponding child already exists */ bool exists = false; + + unsigned num_abandoned = 0; + _children.for_each_child([&] (Child const &child) { - if (!child.abandoned() - && child.name() == start_node.attribute_value("name", Child_policy::Name())) - exists = true; }); - if (exists) { + if (child.name() == start_node.attribute_value("name", Child_policy::Name())) { + if (child.abandoned()) + num_abandoned++; + else + exists = true; + } + }); + + /* skip start node if corresponding child already exists */ + if (exists) + return; + + /* prevent queuing up abandoned children with the same name */ + if (num_abandoned > 1) return; - } if (used_ram.value > avail_ram.value) { error("RAM exhausted while starting childen");