diff --git a/src/proc/control/looper.hpp b/src/proc/control/looper.hpp index 148f8bc24..49a7794b0 100644 --- a/src/proc/control/looper.hpp +++ b/src/proc/control/looper.hpp @@ -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() diff --git a/src/proc/control/proc-dispatcher.cpp b/src/proc/control/proc-dispatcher.cpp index 560f1a2b0..d07d2b281 100644 --- a/src/proc/control/proc-dispatcher.cpp +++ b/src/proc/control/proc-dispatcher.cpp @@ -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 diff --git a/tests/core/proc/control/dispatcher-looper-test.cpp b/tests/core/proc/control/dispatcher-looper-test.cpp index 0762719b0..23ab76a85 100644 --- a/tests/core/proc/control/dispatcher-looper-test.cpp +++ b/tests/core/proc/control/dispatcher-looper-test.cpp @@ -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()); diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 614e145a2..b487f6306 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -11275,6 +11275,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +