mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
sequence: add keep-going feature
When enabling the 'keep_going' config attribute, the component will carry on in case a child exited with an error. In addition, if the 'restart' attribute is set it will start executing the children from the beginning.
This commit is contained in:
parent
1583782446
commit
dd6bd0f880
@ -1,7 +1,7 @@
|
||||
This directory contains a simple utility to serialize the execution of
|
||||
multiple components. It is configured with "start" XML nodes much like
|
||||
_init_ however this component relies on its parent to manage all routing
|
||||
and resources, with the exception of a "config" ROM. No services are
|
||||
multiple components. It is configured with '<start>' XML nodes much like
|
||||
_init_. However, this component relies on its parent to manage all routing
|
||||
and resources, with the exception of a 'config' ROM. No services are
|
||||
propagated from children to the parent.
|
||||
|
||||
A sample configuration to start a consumer after a producer has exited:
|
||||
@ -24,3 +24,17 @@ A sample configuration to start a consumer after a producer has exited:
|
||||
! </start>
|
||||
! </config>
|
||||
! </start>
|
||||
|
||||
There are a few optional '<config>' attributes that control the way the
|
||||
component operates:
|
||||
|
||||
* 'repeat' will instruct the component to repeat the sequence again
|
||||
starting from the first '<start>' node when it has reached the end.
|
||||
The default is 'false'.
|
||||
|
||||
* 'keep_going' will instruct the component to start the next child
|
||||
in case the previous one exited with an error. The default is 'false'.
|
||||
|
||||
* 'restart' instructs the component to start from the top of the
|
||||
sequence. It is only evaluted when 'keep_going' is enabled. The
|
||||
default is 'false'.
|
||||
|
@ -75,6 +75,8 @@ struct Sequence::Child : Genode::Child_policy
|
||||
|
||||
Genode::Child _child { _env.rm(), _env.ep().rpc_ep(), *this };
|
||||
|
||||
int _exit_value = -1;
|
||||
|
||||
Child(Genode::Env &env,
|
||||
Xml_node const &start_node,
|
||||
Signal_context_capability exit_handler)
|
||||
@ -96,6 +98,8 @@ struct Sequence::Child : Genode::Child_policy
|
||||
destroy(_services_heap, &service); });
|
||||
}
|
||||
|
||||
int exit_value() const { return _exit_value; }
|
||||
|
||||
|
||||
/****************************
|
||||
** Child_policy interface **
|
||||
@ -138,18 +142,14 @@ struct Sequence::Child : Genode::Child_policy
|
||||
Pd_session_capability ref_pd_cap() const override { return _env.pd_session_cap(); }
|
||||
|
||||
/**
|
||||
* If the exit is successful then queue a child reload via a signal,
|
||||
* otherwise exit this parent component.
|
||||
* Always queue a reload signal and store the exit value. The
|
||||
* parent will then determine which action to take by looking
|
||||
* at the exit value.
|
||||
*/
|
||||
void exit(int exit_value) override
|
||||
{
|
||||
if (exit_value == 0)
|
||||
_exit_transmitter.submit();
|
||||
else {
|
||||
error("child \"", name(), "\" exited with exit value ", exit_value);
|
||||
_env.parent().exit(exit_value);
|
||||
sleep_forever();
|
||||
}
|
||||
_exit_value = exit_value;
|
||||
_exit_transmitter.submit();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,7 +230,31 @@ struct Sequence::Main
|
||||
|
||||
void Sequence::Main::start_next_child()
|
||||
{
|
||||
if (child.constructed())
|
||||
bool const constructed = child.constructed();
|
||||
|
||||
/*
|
||||
* In case the child exited with an error check if we
|
||||
* still should keep-going and when doing so if the
|
||||
* sequence should be restarted.
|
||||
*/
|
||||
if (constructed && child->exit_value()) {
|
||||
bool const keep_going = config_xml.attribute_value("keep_going", false);
|
||||
bool const restart = config_xml.attribute_value("restart", false);
|
||||
|
||||
warning("child \"", child->name(), "\" exited with exit value ",
|
||||
child->exit_value());
|
||||
|
||||
if (!keep_going) {
|
||||
env.parent().exit(child->exit_value());
|
||||
sleep_forever();
|
||||
}
|
||||
|
||||
warning("keep-going", restart ? " starting from the beginning" : "");
|
||||
if (restart)
|
||||
next_xml_index = 0;
|
||||
}
|
||||
|
||||
if (constructed)
|
||||
child.destruct();
|
||||
|
||||
try { while (true) {
|
||||
|
Loading…
Reference in New Issue
Block a user