Session-Subsystem(#318): investigation of locking sanity (ongoing...)
Found an inconsistency and a deadlock! See proc-dispatcher.cpp, the lambda embedded into the start() operation!
This commit is contained in:
parent
34686713d4
commit
77303ad007
8 changed files with 126 additions and 91 deletions
|
|
@ -95,9 +95,11 @@ namespace lumiera {
|
|||
virtual bool shouldStart (lumiera::Option&) =0;
|
||||
|
||||
|
||||
/** how to start up this subsystem. Failure to start up
|
||||
* usually terminates the whole application. When this subsystem
|
||||
* ceases to work, it must assure to activate the given signal.
|
||||
/** attempt to bring up this subsystem up. On return, the
|
||||
* subsystem must be operational, according to checkRunningState().
|
||||
* Failure to start up usually terminates the whole application.
|
||||
* When this subsystem ceases to work, it must ensure to activate
|
||||
* the given callback signal.
|
||||
* @param options may be influencing the operation mode
|
||||
* @param termination to be signalled by the subsystem.
|
||||
* @warning termination must be signalled reliably.
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ namespace lumiera {
|
|||
throw error::Logic("Subsystem "+string(*susy)+" failed to start");
|
||||
}
|
||||
|
||||
if (!and_all (susy->getPrerequisites(), isRunning() ))
|
||||
if (not and_all (susy->getPrerequisites(), isRunning() ))
|
||||
{
|
||||
susy->triggerShutdown();
|
||||
throw error::State("Unable to start all prerequisites of Subsystem "+string(*susy));
|
||||
|
|
|
|||
|
|
@ -128,6 +128,14 @@ namespace control {
|
|||
|
||||
|
||||
public:
|
||||
/** start the session loop thread
|
||||
* @param notification callback to invoke on thread termination
|
||||
* @remark _in theory_ this ctor could block, since it waits for the thread
|
||||
* actually to get operational and it waits for the SessionCommand interface
|
||||
* to be opened. The latter _should not_ run into any obstacles, because
|
||||
* in case it does, the main application thread is deadlocked on startup.
|
||||
* Such might happen indirectly, when something depends on "the Session"
|
||||
*/
|
||||
DispatcherLoop (Subsys::SigTerm notification)
|
||||
: ThreadJoinable("Lumiera Session"
|
||||
, bind (&DispatcherLoop::runSessionThread, this, notification))
|
||||
|
|
@ -315,7 +323,14 @@ namespace control {
|
|||
|
||||
|
||||
|
||||
/** */
|
||||
/** starting the ProcDispatcher means to start the session subsystem.
|
||||
* @return `false` when _starting_ failed since it is already running...
|
||||
* @remark this function implements the start operation for the »session subsystem«.
|
||||
* More specifically, this operation starts a new thread to perform the
|
||||
* _session loop,_ which means to perform commands and trigger the builder.
|
||||
* It might block temporarily for synchronisation with this new thread and
|
||||
* while opening the SessionCommand facade.
|
||||
*/
|
||||
bool
|
||||
ProcDispatcher::start (Subsys::SigTerm termNotification)
|
||||
{
|
||||
|
|
@ -326,7 +341,7 @@ namespace control {
|
|||
new DispatcherLoop (
|
||||
[=] (string* problemMessage)
|
||||
{
|
||||
runningLoop_.reset();
|
||||
runningLoop_.reset(); //////////////////////TODO: (1) Race in ProcDispatcher (2) Deadlock because the Thread attempts to reap itself
|
||||
termNotification(problemMessage);
|
||||
}));
|
||||
|
||||
|
|
@ -336,7 +351,10 @@ namespace control {
|
|||
}
|
||||
|
||||
|
||||
/** */
|
||||
/** whether the »session subsystem« is operational.
|
||||
* @return `true` if the session loop thread has been fully
|
||||
* started and is not (yet) completely terminated.
|
||||
*/
|
||||
bool
|
||||
ProcDispatcher::isRunning()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,10 +23,29 @@
|
|||
|
||||
/** @file proc-dispatcher.hpp
|
||||
** Dispatch and execute mutation operations on the High-level model.
|
||||
** //TODO
|
||||
** The ProcDispatcher is the application facility to back and support working
|
||||
** on the Session. While the session itself is just a data structure, _operating_
|
||||
** the session means to process commands changing that data structure and it means
|
||||
** to evaluate the _session model_ and _build_ a render nodes network in accordance
|
||||
** to that model's meaning. This _operation aspect_ of the session thus has a lifecycle
|
||||
** and this is what we call the "session subsystem" within the application. When this is
|
||||
** running, the SessionCommand facade is opened, accepting commands to work on the session.
|
||||
** Such commands are passed through a dispatch queue to ensure consistent session state
|
||||
** and to force strictly sequential processing of commands. Moreover, the ProcDispatcher's
|
||||
** responsibility is to care for triggering the Builder after any changes induced by those
|
||||
** commands. The Builder is guaranteed to run _eventually_, yet with some leeway.
|
||||
**
|
||||
** Talking of state, independent of the lifecycle running state, the ProcDispatcher can be
|
||||
** _activated or deactivated_. In active state, commands are dequeued and processed, while
|
||||
** in inactive state commands are just accepted and queued, assuming the SessionCommand
|
||||
** interface is currently opened. This activation state is controlled by the session
|
||||
** datastructure itself, more precisely the SessionManager. A session can be stored,
|
||||
** closed, reset and loaded with existing content from persistent storage, and only
|
||||
** when the data structure is complete and consistent, processing can be enabled.
|
||||
**
|
||||
** @see Command
|
||||
** @see Session
|
||||
** @see proc-dispatcher.cpp for details of operational semantics
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
@ -54,7 +73,13 @@ namespace control {
|
|||
|
||||
|
||||
/**
|
||||
* @todo Type-comment
|
||||
* Guard to manage processing commands working on the session.
|
||||
* A static application facility, actually backing and implementing
|
||||
* the »session subsystem«. Embedded within the implementation of this
|
||||
* class is the _»session loop thread«_ to perform any session mutation
|
||||
* commands and to operate the Builder, which translates the session
|
||||
* contents into a render nodes network. Also embedded herein is
|
||||
* the implementation of proc::control::SessionCommandService
|
||||
*/
|
||||
class ProcDispatcher
|
||||
: public lib::Sync<>
|
||||
|
|
|
|||
|
|
@ -47,8 +47,9 @@ namespace proc {
|
|||
{
|
||||
operator string() const { return "Session"; }
|
||||
|
||||
/** @remarks there is no need explicitly to start the session core,
|
||||
* since it will usually be pulled up as prerequisite */
|
||||
/** @remarks there is no need explicitly to start the session,
|
||||
* since it is passive, waiting for invocations and will be
|
||||
* pulled up as prerequisite of other subsystems. */
|
||||
bool
|
||||
shouldStart (Option&) override
|
||||
{
|
||||
|
|
|
|||
|
|
@ -56,14 +56,14 @@ namespace proc {
|
|||
struct Facade
|
||||
{
|
||||
/** provide a descriptor for lumiera::AppState,
|
||||
* wired accordingly to allow main to bring up
|
||||
* a editing session, possibly by loading an
|
||||
* existing session from storage. */
|
||||
* wired accordingly to allow `main()` to boot
|
||||
* the support infrastructure for loading of
|
||||
* and working on the editing session. */
|
||||
static lumiera::Subsys& getSessionDescriptor();
|
||||
|
||||
|
||||
/** provide a descriptor for lumiera::AppState,
|
||||
* wired accordingly to allow main to bring up
|
||||
* wired accordingly to allow `main()` to bring up
|
||||
* the render / playback coordination and
|
||||
* output management subsystem. */
|
||||
static lumiera::Subsys& getPlayOutDescriptor();
|
||||
|
|
|
|||
|
|
@ -167,8 +167,8 @@ namespace test {
|
|||
CHECK (looper.shallLoop());
|
||||
|
||||
setup.has_commands_in_queue = false;
|
||||
looper.markStateProcessed();
|
||||
looper.markStateProcessed();
|
||||
looper.markStateProcessed(); // after command processing
|
||||
looper.markStateProcessed(); // after builder run
|
||||
|
||||
CHECK (not looper.requireAction());
|
||||
CHECK (not looper.isWorking());
|
||||
|
|
|
|||
|
|
@ -330,8 +330,7 @@
|
|||
meint: zwei gekoppelte Statusvariable
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1481767706906" ID="ID_815807707" MODIFIED="1481767710581" TEXT="bekomme dort Zustand"/>
|
||||
<node CREATED="1481767720576" ID="ID_714877064" MODIFIED="1481767729611" TEXT="muß dort Locking verwenden"/>
|
||||
|
|
@ -358,8 +357,7 @@
|
|||
oder muß PImpl als Interface exponieren
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1481767831105" ID="ID_1351930491" MODIFIED="1481768989667" TEXT="fragiler Lebenszyklus">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -371,8 +369,7 @@
|
|||
meint: zwei gekoppelte Statusvariable
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -463,8 +460,7 @@
|
|||
<i>ist nicht</i> "die Session
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1482464332981" ID="ID_1523357281" MODIFIED="1482464350688" TEXT="Session Subsystem == Session Dispatcher Loop Thread">
|
||||
|
|
@ -487,8 +483,7 @@
|
|||
das Lock sorgt hier für konsistenten Zustand und Sichtbarkeit (memory barrier)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1481684394544" ID="ID_1314197501" MODIFIED="1481684422640" TEXT="Back-End">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -500,12 +495,23 @@
|
|||
Lock ist hier das Dispatcher-Lock
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1481599468712" ID="ID_1273965744" MODIFIED="1481599482440" TEXT="Vorsicht beim Anhalten (Deadlock-Gefahr)">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1483477519974" ID="ID_1731425552" MODIFIED="1483477535864" TEXT="Term-Signal könnte blocken">
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1483484052785" ID="ID_667055412" MODIFIED="1483484091053" TEXT="Race beim runningLoop_.reset()">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node CREATED="1483490316758" ID="ID_1734989824" MODIFIED="1483490376306" TEXT="nur das Term-Signal kann DispatcherLoop deleten">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1483490459499" ID="ID_1006586365" MODIFIED="1483490478840" TEXT="Thread will sich selbst reapen ==> Deadlock">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1482464502542" ID="ID_284397306" MODIFIED="1482464609118" TEXT="Vorsicht beim Schließen der Session">
|
||||
<arrowlink COLOR="#5a97df" DESTINATION="ID_1378897740" ENDARROW="Default" ENDINCLINATION="9540;0;" ID="Arrow_ID_1446486242" STARTARROW="None" STARTINCLINATION="9540;0;"/>
|
||||
|
|
@ -532,8 +538,7 @@
|
|||
...wenn jemand zugreift
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1481599603757" ID="ID_812618450" MODIFIED="1481599612320" TEXT="Operation auf dem SessionManager"/>
|
||||
<node CREATED="1481599612812" ID="ID_1970476027" MODIFIED="1481599618598" TEXT="der ist Singleton"/>
|
||||
|
|
@ -558,8 +563,7 @@
|
|||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -586,8 +590,7 @@
|
|||
<i>bevor</i> die Dispatcher-loop angehalten wird
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1481778397600" ID="ID_1997192349" MODIFIED="1481778409498" TEXT="bereits wenn Anhalten signalisiert wird"/>
|
||||
<node CREATED="1481778409942" ID="ID_100284739" MODIFIED="1481778419113" TEXT="zur Sicherheit nochmal im dtor"/>
|
||||
|
|
@ -604,8 +607,7 @@
|
|||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1482464658193" HGAP="-19" ID="ID_726798260" MODIFIED="1482464708932" TEXT="Ausgestaltung" VSHIFT="24">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1482464658193" HGAP="-14" ID="ID_726798260" MODIFIED="1482711954690" TEXT="Ausgestaltung" VSHIFT="29">
|
||||
<node CREATED="1482465840843" ID="ID_818984499" MODIFIED="1482465853543" TEXT="Entwurf">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
<node CREATED="1482464676366" FOLDED="true" ID="ID_1064506750" MODIFIED="1482464760237" TEXT="bekommt Nachrichten vom UI-Bus">
|
||||
|
|
@ -638,8 +640,7 @@
|
|||
wenn in der UI ein InvocationTrail angelegt wird.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1482466104359" ID="ID_235553653" MODIFIED="1482466115902" TEXT="speichert aber eigentlich nur die Cmd-ID">
|
||||
<icon BUILTIN="idea"/>
|
||||
|
|
@ -658,8 +659,7 @@
|
|||
<i>kann offen bleiben</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<node CREATED="1482466246933" ID="ID_870716233" MODIFIED="1482466256655" TEXT="hängt von der Verwendung ab"/>
|
||||
<node CREATED="1482466257027" ID="ID_1491453181" MODIFIED="1482466260134" TEXT="von InvocationTrail"/>
|
||||
<node CREATED="1482466260627" ID="ID_1708185529" MODIFIED="1482466265989" TEXT="wie Commands im UI gebunden werden"/>
|
||||
|
|
@ -676,8 +676,7 @@
|
|||
reine ID-Wirtschaft <i>wäre möglich</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1482466285359" ID="ID_1077952925" MODIFIED="1482466316309" TEXT="Zugriff auf proc::control::Command is OK">
|
||||
|
|
@ -11177,7 +11176,11 @@
|
|||
</node>
|
||||
<node CREATED="1481777397542" ID="ID_1147135932" MODIFIED="1481778447806" TEXT="DispatcherLoop stirbt"/>
|
||||
<node CREATED="1481777410972" ID="ID_457965735" MODIFIED="1481777418982" TEXT="sigTerm"/>
|
||||
<node CREATED="1481778453137" ID="ID_1895977623" MODIFIED="1481778465907" TEXT="bewirkt reapen des LoopThread"/>
|
||||
<node CREATED="1481778453137" ID="ID_1895977623" MODIFIED="1481778465907" TEXT="bewirkt reapen des LoopThread">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1482712050992" ID="ID_336551514" MODIFIED="1482712065548" TEXT="wie genau">
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -11186,7 +11189,11 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1481826329819" ID="ID_1238318698" MODIFIED="1481826431105" TEXT="enqueue commands concurrently">
|
||||
<node CREATED="1481827297122" ID="ID_860095678" MODIFIED="1481827311268" TEXT="FIFO for regular commands"/>
|
||||
<node CREATED="1481827312024" ID="ID_850193431" MODIFIED="1481827318187" TEXT="LIFO for priority requests"/>
|
||||
<node CREATED="1481827312024" ID="ID_850193431" MODIFIED="1481827318187" TEXT="LIFO for priority requests">
|
||||
<node CREATED="1482712100745" ID="ID_1387300775" MODIFIED="1482712106824" TEXT="vorerst nicht implementiert">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1481826431861" ID="ID_328583048" MODIFIED="1481826440935" TEXT="process sequentially"/>
|
||||
<node CREATED="1481826441884" ID="ID_952327020" MODIFIED="1481826446791" TEXT="until queue is empty"/>
|
||||
|
|
@ -11230,8 +11237,7 @@
|
|||
Guard beim Zugang über das Interface
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1481918074269" ID="ID_1984339005" MODIFIED="1481918091136">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
|
|
@ -11243,8 +11249,7 @@
|
|||
<i>nur sie</i> ist atomar
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -11259,8 +11264,7 @@
|
|||
<b>nur ein Thread</b> für Commands und Builder
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#171ccb" DESTINATION="ID_1214851922" ENDARROW="Default" ENDINCLINATION="53;-5;" ID="Arrow_ID_1745317422" STARTARROW="None" STARTINCLINATION="42;2;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1481918174199" ID="ID_364234189" MODIFIED="1481918180762" TEXT="essentiell für Konsitenz der Session"/>
|
||||
|
|
@ -11300,8 +11304,7 @@
|
|||
Ticket <font color="#e90426">#1054</font>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="bell"/>
|
||||
<node CREATED="1482197270202" ID="ID_221875120" MODIFIED="1482197288634" TEXT="neues API auf unserem Thread-Wrapper schaffen">
|
||||
<icon BUILTIN="yes"/>
|
||||
|
|
@ -11348,8 +11351,7 @@
|
|||
OO rocks!
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -11362,8 +11364,8 @@
|
|||
<node CREATED="1481828624042" ID="ID_1970372601" MODIFIED="1481828635748" TEXT="Looper für Schleifen-Logik"/>
|
||||
<node CREATED="1481828639584" ID="ID_1344182776" MODIFIED="1481828648402" TEXT="CommandQueue"/>
|
||||
</node>
|
||||
<node CREATED="1481778549940" HGAP="50" ID="ID_676848252" MODIFIED="1482464798892" TEXT="DispatcherLoop" VSHIFT="1">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1481778549940" HGAP="50" ID="ID_676848252" MODIFIED="1482712315146" TEXT="DispatcherLoop" VSHIFT="1">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1481778741546" ID="ID_684867533" MODIFIED="1481778755694" TEXT="öffnet Session-Interface">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
|
|
@ -11387,42 +11389,33 @@
|
|||
<arrowlink COLOR="#5242a4" DESTINATION="ID_1311208726" ENDARROW="Default" ENDINCLINATION="2;-45;" ID="Arrow_ID_313252247" STARTARROW="None" STARTINCLINATION="-186;-13;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1481831642376" ID="ID_1301681872" MODIFIED="1481831650435" TEXT="Checkpoint bieten">
|
||||
<node CREATED="1482365008444" ID="ID_1520027430" MODIFIED="1482365011517" TEXT="wirklich">
|
||||
<node CREATED="1481831642376" ID="ID_1301681872" MODIFIED="1482712297004" TEXT="Checkpoint bieten">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1482365008444" ID="ID_1520027430" MODIFIED="1482712182562" TEXT="warum">
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
<node CREATED="1482365012947" ID="ID_10844185" MODIFIED="1482365019558" TEXT="Konzept nicht klar"/>
|
||||
<node CREATED="1482365020242" ID="ID_981800101" MODIFIED="1482365065006" TEXT="ursprünglich...">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...meinte ich, so etwas wie den Sequence-Point von C++
|
||||
</p>
|
||||
<p>
|
||||
also die Stelle, an der "die Zahnräder ineinander greifen"
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<node CREATED="1482365012947" ID="ID_10844185" MODIFIED="1482712196344" TEXT="um zuverlässig anhalten zu können"/>
|
||||
<node CREATED="1482712199900" ID="ID_1990071363" MODIFIED="1482712291119" TEXT="Checkpoint == Zustand ausgeglichen">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1482365070571" ID="ID_1387994688" MODIFIED="1482365108042" TEXT="Notwendigkeit zweifelhaft">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<node CREATED="1482712212930" ID="ID_1065088226" MODIFIED="1482712286050" TEXT="das heißt">
|
||||
<icon BUILTIN="info"/>
|
||||
<node CREATED="1482712227048" ID="ID_172281578" MODIFIED="1482712234491" TEXT="keine schwebenden Zustandsänderungen"/>
|
||||
<node CREATED="1482712235016" ID="ID_943771142" MODIFIED="1482712249961" TEXT="Alle zustands-Relevanten Änderungen sind ausgewertet"/>
|
||||
<node CREATED="1482712250461" ID="ID_610930154" MODIFIED="1482712260744" TEXT="alle Prädikate spiegeln den wirklichen Zustand wider"/>
|
||||
<node CREATED="1482712261876" ID="ID_47966817" MODIFIED="1482712282765">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
es scheint, als würde ich eine Implementierung hinbekommen,
|
||||
</p>
|
||||
<p>
|
||||
die (fast) nur auf logischen Zusammenhängen beruht
|
||||
Kontrollfluß ist <i>nicht</i> in einer Arbeitsfunktion
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1481831747042" ID="ID_134003952" MODIFIED="1481831788672" TEXT="sperrbar sein">
|
||||
|
|
@ -11443,8 +11436,7 @@
|
|||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -11505,8 +11497,7 @@
|
|||
<i>billig:</i> unsere Zeit-Lib nutzen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1482430715396" ID="ID_1005651794" MODIFIED="1482430722896" TEXT="nicht besonders schön">
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
|
|
@ -11572,8 +11563,7 @@
|
|||
generischer Überlegungen implementiert
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1482202243253" ID="ID_1342399342" MODIFIED="1482202264229" TEXT="verhält er sich dann richtig">
|
||||
|
|
@ -12053,8 +12043,7 @@
|
|||
Ticket <font color="#ba0c3f">#886</font>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue