Looper: other (better?) idea how to handle "builder dirty" automatically

...this means to turn Looper into a state machine.
Yet it seems more feasible, since the DispatcherLoop has a nice
checkpoint after each iteration through the while loop, and we'd
keep that whole builder-dirty business completely confined within
the Looper (with a little help of the DispatcherLoop)

Let's see if the state transition logic can actually be implemented
based just on such a checkpoint....?
This commit is contained in:
Fischlurch 2016-12-20 03:53:48 +01:00
parent 14e0d65468
commit 6073df3554
4 changed files with 103 additions and 17 deletions

View file

@ -116,6 +116,22 @@ namespace control {
disabled_ = not yes;
}
/** invoking this function signals
* that all consequences of past state changes
* have been processed and duly resolved.
*/
void
markStateProcessed()
{
UNIMPLEMENTED("state transition logic");
}
bool
hasPendingChanges() const
{
UNIMPLEMENTED("state transition logic");
}
/** state fusion to control (timed) wait */
bool
requireAction()

View file

@ -173,6 +173,7 @@ namespace control {
else
if (looper_.isWorking())
processCommands();
looper_.markStateProcessed();
}
}
catch (lumiera::Error& problem)
@ -199,13 +200,12 @@ namespace control {
bool
stateIsSynched()
{
bool duelyResolved = false;
UNIMPLEMENTED("find out if all pending state changes are carried out.");
if (not duelyResolved and calledFromWithinSessionThread())
if (looper_.hasPendingChanges() and calledFromWithinSessionThread())
throw error::Fatal("Possible Deadlock. "
"Attempt to synchronise to a command processing check point "
"from within the (single) session thread."
, error::LUMIERA_ERROR_LIFECYCLE);
return looper_.hasPendingChanges();
}
void

View file

@ -79,7 +79,6 @@ namespace test {
struct Setup
{
bool has_commands_in_queue = false;
bool builder_is_dirty = false;
Looper
install()
@ -324,7 +323,6 @@ namespace test {
CHECK ( looper.isIdle());
setup.has_commands_in_queue = true; // regular command processing
setup.builder_is_dirty = true; // need to re-build after issuing a command
CHECK ( looper.requireAction());
CHECK (not looper.isDisabled());
@ -332,19 +330,52 @@ namespace test {
CHECK ( looper.needBuild());
CHECK (not looper.isIdle());
setup.has_commands_in_queue = false; // done with the commands thus far
looper.markStateProcessed(); // at least one command has been handled
CHECK ( looper.requireAction());
CHECK (not looper.isDisabled());
CHECK ( looper.isWorking());
CHECK ( looper.needBuild()); // ...note: still needs build
CHECK (not looper.isIdle());
CHECK (isFast (looper.getTimeout()));
looper.markStateProcessed(); // next processing round: further command(s) processed,
// yet still more commands pending...
CHECK ( looper.requireAction());
CHECK (not looper.isDisabled());
CHECK ( looper.isWorking());
CHECK ( looper.needBuild()); // ...note: still needs build
CHECK (not looper.isIdle());
CHECK (isFast (looper.getTimeout()));
looper.markStateProcessed(); // let's assume we've hit the long timeout
// and thus triggered one the builder run now,
// but still more commands are pending...
CHECK ( looper.requireAction());
CHECK (not looper.isDisabled());
CHECK ( looper.isWorking());
CHECK ( looper.needBuild()); // ...note: again needs build
CHECK (not looper.isIdle());
CHECK (isFast (looper.getTimeout()));
setup.has_commands_in_queue = false; // now emptied our queue
looper.markStateProcessed(); // at least one command has been handled
CHECK (not looper.requireAction());
CHECK (not looper.isDisabled());
CHECK (not looper.isWorking());
CHECK ( looper.needBuild()); // ...note: still needs build
CHECK ( looper.isIdle());
CHECK (isFast (looper.getTimeout()));
CHECK (not looper.isIdle());
setup.builder_is_dirty = false;
looper.markStateProcessed(); // next processing round: invoked builder,
// and no more commands commands pending...
CHECK (not looper.requireAction());
CHECK (not looper.isDisabled());
CHECK (not looper.isWorking());
@ -360,12 +391,12 @@ namespace test {
CHECK (not looper.isDisabled());
CHECK ( looper.isWorking());
CHECK (not looper.needBuild()); // ...note: command not yet processed: no need to re-build
CHECK ( looper.isIdle());
CHECK (not looper.isIdle());
CHECK (isSlow (looper.getTimeout()));
setup.builder_is_dirty = true; // now let's assume one command has been processed
looper.markStateProcessed(); // now let's assume one command has been processed
CHECK ( looper.requireAction());
CHECK (not looper.isDisabled());
@ -399,6 +430,7 @@ namespace test {
setup.has_commands_in_queue = false; // done with the commands
looper.markStateProcessed();
CHECK (not looper.requireAction());
CHECK (not looper.isDisabled());
@ -429,7 +461,7 @@ namespace test {
looper.enableProcessing(false); // disable processing
setup.builder_is_dirty = false; // let's assume builder was running and is now finished
looper.markStateProcessed(); // let's assume builder was running and is now finished
CHECK (not looper.requireAction());
CHECK ( looper.isDisabled());
@ -452,7 +484,7 @@ namespace test {
setup.has_commands_in_queue = true; // more commands again
setup.builder_is_dirty = true; // ...and let's assume one command has already been processed
looper.markStateProcessed(); // ...and let's assume one command has already been processed
CHECK ( looper.requireAction());
CHECK (not looper.isDisabled());
@ -471,7 +503,8 @@ namespace test {
CHECK (isFast (looper.getTimeout()));
setup.has_commands_in_queue = false; // and even when done all commands
setup.has_commands_in_queue = false; // and even when done with all commands...
looper.markStateProcessed();
CHECK ( looper.requireAction());
CHECK (not looper.isDisabled());
@ -482,7 +515,7 @@ namespace test {
CHECK (isFast (looper.getTimeout()));
setup.builder_is_dirty = false;
looper.markStateProcessed();
CHECK ( looper.requireAction());
CHECK (not looper.isDisabled());

View file

@ -11275,6 +11275,43 @@
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node CREATED="1482202066204" HGAP="23" ID="ID_41541843" MODIFIED="1482202078184" TEXT="L&#xf6;sungnsansatz" VSHIFT="16">
<icon BUILTIN="help"/>
<node CREATED="1482202080675" ID="ID_12774028" MODIFIED="1482202126233" TEXT="CommandQueue mu&#xdf; helfen und dirty-state verwalten">
<icon BUILTIN="button_cancel"/>
<node CREATED="1482202099752" ID="ID_434677221" MODIFIED="1482202114130" TEXT="geht, weil sie wei&#xdf;, wann ein Command wirklich l&#xe4;uft"/>
<node CREATED="1482202114630" ID="ID_1833945556" MODIFIED="1482202123872" TEXT="unsch&#xf6;n, weil wir nun massive Kopplung haben"/>
</node>
<node CREATED="1482202127252" ID="ID_1720469294" MODIFIED="1482202135479" TEXT="Looper in State-machine verwandeln">
<node CREATED="1482202136235" ID="ID_239151488" MODIFIED="1482202175455" TEXT="schwierig">
<icon BUILTIN="stop-sign"/>
</node>
<node CREATED="1482202142818" ID="ID_1412852448" MODIFIED="1482202181794" TEXT="ben&#xf6;tigt Hilfe von der DispatcherLoop">
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1482202156416" ID="ID_1161547825" MODIFIED="1482202183920" TEXT="geht aber: nach jedem WHILE-Durchlauf">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1482202165423" ID="ID_1845799711" MODIFIED="1482202186673" TEXT="schaut sauberer aus">
<icon BUILTIN="ksmiletris"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1482202187620" ID="ID_259250017" MODIFIED="1482202197691" TEXT="Frage: geht es &#xfc;berhaupt zu implementieren">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
<node CREATED="1482202207242" ID="ID_1287224856" MODIFIED="1482202269318" TEXT="Test">
<icon BUILTIN="pencil"/>
<node CREATED="1482202211049" ID="ID_1159832087" MODIFIED="1482202222520" TEXT="komplexen Ablauf als Szenario durchspielen">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1482202223536" ID="ID_374030732" MODIFIED="1482202266018" TEXT="Logik im Looper auf Basis generischer &#xdc;berlegungen implementieren">
<icon BUILTIN="flag-yellow"/>
</node>
<node CREATED="1482202243253" ID="ID_1342399342" MODIFIED="1482202264229" TEXT="verh&#xe4;lt er sich dann richtig">
<icon BUILTIN="help"/>
</node>
</node>
</node>
<node CREATED="1481828583551" ID="ID_436508747" MODIFIED="1481828608672" TEXT="Aufbau">
<node CREATED="1481828611347" ID="ID_160907866" MODIFIED="1481828614071" TEXT="Front-End"/>