Library: policy for lifecycle hooks
after some further mulling over the design, it became clear that a rather loose coupling to the actual usage scenario is preferrable. Thus, instead of devising a fixed scheme how to reflect the thread state, rather the usage can directly hook into some points in the thread lifecycle. So this policy can be reduced to provide additional storage for functon objects.
This commit is contained in:
parent
5f9683ef10
commit
578af05ebd
2 changed files with 148 additions and 13 deletions
|
|
@ -214,9 +214,9 @@ namespace lib {
|
|||
void waitGracePeriod() noexcept;
|
||||
|
||||
/* empty implementation for some policy methods */
|
||||
void handle_begin_thread() { }
|
||||
void handle_after_thread() { }
|
||||
void handle_thread_still_running() { }
|
||||
void handle_begin_thread() { } ///< called immediately at start of thread
|
||||
void handle_after_thread() { } ///< called immediately before end of thread
|
||||
void handle_loose_thread() { } ///< called when destroying wrapper on still running thread
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -253,7 +253,7 @@ namespace lib {
|
|||
}
|
||||
|
||||
void
|
||||
handle_thread_still_running()
|
||||
handle_loose_thread()
|
||||
{
|
||||
BAS::waitGracePeriod();
|
||||
}
|
||||
|
|
@ -283,13 +283,67 @@ namespace lib {
|
|||
}
|
||||
|
||||
void
|
||||
handle_thread_still_running()
|
||||
handle_loose_thread()
|
||||
{
|
||||
ALERT (thread, "Self-managed thread was deleted from outside. Abort.");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Thread Lifecycle Policy Extension:
|
||||
* additionally self-manage the thread-wrapper allocation.
|
||||
* @warning the thread-wrapper must have been heap-allocated.
|
||||
*/
|
||||
template<class BAS, class TAR>
|
||||
struct PolicyLifecycleHook
|
||||
: PolicyLaunchOnly<BAS>
|
||||
{
|
||||
using BasePol = PolicyLaunchOnly<BAS>;
|
||||
using BasePol::BasePol;
|
||||
|
||||
using Hook = function<void(TAR&)>;
|
||||
|
||||
Hook hook_beginThread{};
|
||||
Hook hook_afterThread{};
|
||||
Hook hook_looseThread{};
|
||||
|
||||
TAR&
|
||||
castInstance()
|
||||
{
|
||||
return static_cast<TAR*>(
|
||||
static_cast<void*> (this));
|
||||
}
|
||||
|
||||
void
|
||||
handle_begin_thread()
|
||||
{
|
||||
if (hook_beginThread)
|
||||
hook_beginThread (castInstance());
|
||||
else
|
||||
BasePol::handle_begin_thread();
|
||||
}
|
||||
|
||||
void
|
||||
handle_after_thread()
|
||||
{
|
||||
if (hook_afterThread)
|
||||
hook_afterThread (castInstance());
|
||||
else
|
||||
BasePol::handle_after_thread();
|
||||
}
|
||||
|
||||
void
|
||||
handle_loose_thread()
|
||||
{
|
||||
if (hook_looseThread)
|
||||
hook_looseThread (castInstance());
|
||||
else
|
||||
BasePol::handle_loose_thread();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Thread Lifecycle Policy:
|
||||
* - thread with the ability to publish results
|
||||
|
|
@ -328,7 +382,7 @@ namespace lib {
|
|||
}
|
||||
|
||||
void
|
||||
handle_thread_still_running()
|
||||
handle_loose_thread()
|
||||
{
|
||||
ALERT (thread, "Thread '%s' was not joined. Abort.", BAS::threadID_.c_str());
|
||||
}
|
||||
|
|
@ -360,7 +414,7 @@ namespace lib {
|
|||
~ThreadLifecycle()
|
||||
{
|
||||
if (Policy::isLive())
|
||||
Policy::handle_thread_still_running();
|
||||
Policy::handle_loose_thread();
|
||||
}
|
||||
|
||||
/** derived classes may create a disabled thread */
|
||||
|
|
@ -423,6 +477,40 @@ namespace lib {
|
|||
return move(*this);
|
||||
}
|
||||
|
||||
template<typename HOOK>
|
||||
Launch&&
|
||||
atStart (HOOK&& hook)
|
||||
{
|
||||
return addHook (&Policy::hook_beginThread, forward<HOOK> (hook));
|
||||
}
|
||||
|
||||
template<typename HOOK>
|
||||
Launch&&
|
||||
atEnd (HOOK&& hook)
|
||||
{
|
||||
return addHook (&Policy::hook_afterThread, forward<HOOK> (hook));
|
||||
}
|
||||
|
||||
template<typename HOOK>
|
||||
Launch&&
|
||||
onOrphan (HOOK&& hook)
|
||||
{
|
||||
return addHook (&Policy::hook_looseThread, forward<HOOK> (hook));
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename HOOK, class FUN>
|
||||
Launch&&
|
||||
addHook (FUN Policy::*storedHook, HOOK&& hook)
|
||||
{
|
||||
return addLayer ([storedHook, hook = forward<HOOK>(hook)]
|
||||
(ThreadLifecycle& wrapper)
|
||||
{
|
||||
wrapper.*storedHook = move (hook);
|
||||
chain (wrapper);
|
||||
});
|
||||
}
|
||||
|
||||
Launch&&
|
||||
addLayer (Act action)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -65206,6 +65206,7 @@
|
|||
</node>
|
||||
<node CREATED="1696529718984" ID="ID_1539716722" MODIFIED="1696529944892" TEXT="zusätzlichen Erweiterungspunkt nutzen">
|
||||
<arrowlink COLOR="#fdfcc6" DESTINATION="ID_1373519021" ENDARROW="Default" ENDINCLINATION="-114;10;" ID="Arrow_ID_736802000" STARTARROW="None" STARTINCLINATION="116;8;"/>
|
||||
<arrowlink COLOR="#fdfcc6" DESTINATION="ID_1004228427" ENDARROW="Default" ENDINCLINATION="-114;10;" ID="Arrow_ID_936715522" STARTARROW="None" STARTINCLINATION="116;8;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1696529962087" ID="ID_683965677" MODIFIED="1696531663483" TEXT="ownership wird hier gekapert">
|
||||
|
|
@ -65310,6 +65311,26 @@
|
|||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1696899336883" ID="ID_241659538" MODIFIED="1696899355344" TEXT="andere Idee: man könnte nun Variante-1 auf Variante-2 zurückführen">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1696899356785" ID="ID_1810857858" MODIFIED="1696899370834" TEXT="...und zwar weil Variante-1 jetzt ziemlich hohl geworden ist"/>
|
||||
<node CREATED="1696899371359" ID="ID_204770506" MODIFIED="1696899384536" TEXT="im Besonderen wird gar keine spezielle Storage benötigt"/>
|
||||
<node CREATED="1696899394883" ID="ID_221270967" MODIFIED="1696899414119" TEXT="das heißt: das könnte genausogut ein lifecycle-Hook machen">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1696899431703" ID="ID_804029707" MODIFIED="1696899484220" TEXT="...und dieser würde eine ThreadLifecycle-Instanz als Argument bekommen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...und wir wären aus der Nummer raus: das ist nämlich oberhalb der protected inheritance
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1696532404400" ID="ID_1917558827" MODIFIED="1696539443047" TEXT="Variante-2 : optional-Lifecycle">
|
||||
|
|
@ -65326,8 +65347,8 @@
|
|||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1696532676404" ID="ID_91266848" MODIFIED="1696624166370" TEXT="Front-End">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node COLOR="#5b280f" CREATED="1696532676404" ID="ID_91266848" MODIFIED="1696934197232" TEXT="Front-End">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1696532680835" ID="ID_553798887" MODIFIED="1696536376316">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
|
|
@ -65350,8 +65371,7 @@
|
|||
</html></richcontent>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1696536837512" ID="ID_1958442975" MODIFIED="1696624184191" TEXT="Lebenszyklus-Zustand wird atomar verwaltet (acquire_release)">
|
||||
<node COLOR="#5b280f" CREATED="1696536837512" ID="ID_1958442975" MODIFIED="1696934192282" TEXT="Lebenszyklus-Zustand wird atomar verwaltet (acquire_release)">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -65360,7 +65380,28 @@
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1696934162253" ID="ID_724180880" MODIFIED="1696934184964" STYLE="fork" TEXT="das führt zu starker Kopplung im Design">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1696934198943" ID="ID_737180308" MODIFIED="1696934210349" TEXT="besser: funktionale Erweiterungspunkte">
|
||||
<node CREATED="1696934212695" ID="ID_1626568717" MODIFIED="1696934238138" TEXT="diese werden als std::function gespeichert"/>
|
||||
<node CREATED="1696934261703" ID="ID_266607477" MODIFIED="1696934280168" TEXT="und aus entsprechenden Policy-hooks heraus aufgerufen"/>
|
||||
<node CREATED="1696934280923" ID="ID_787857879" MODIFIED="1696934285592" TEXT="Hooks">
|
||||
<node CREATED="1696529808620" ID="ID_78597801" MODIFIED="1696529832292" TEXT="umbenennen: ⟼ handle_after_thread"/>
|
||||
<node CREATED="1696529836760" ID="ID_1004228427" MODIFIED="1696934402647" TEXT="zusätzlich: ⟿ handle_begin_thread">
|
||||
<linktarget COLOR="#fdfcc6" DESTINATION="ID_1004228427" ENDARROW="Default" ENDINCLINATION="-114;10;" ID="Arrow_ID_936715522" SOURCE="ID_1539716722" STARTARROW="None" STARTINCLINATION="116;8;"/>
|
||||
</node>
|
||||
<node CREATED="1696529836760" ID="ID_1153306127" MODIFIED="1696934476853" TEXT="zusätzlich: ⟿ handle_loose_thread">
|
||||
<linktarget COLOR="#fdfcc6" DESTINATION="ID_1153306127" ENDARROW="Default" ENDINCLINATION="-114;10;" ID="Arrow_ID_880044186" SOURCE="ID_1868637331" STARTARROW="None" STARTINCLINATION="263;12;"/>
|
||||
<node CREATED="1696933886929" HGAP="25" ID="ID_796423082" MODIFIED="1696933932976" TEXT="(wird aufgerufen aus dem Destruktor — falls der Thread noch läuft)" VSHIFT="7">
|
||||
<font NAME="SansSerif" SIZE="11"/>
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1696532838782" ID="ID_46766207" MODIFIED="1696532858447" TEXT="der Konflikt im Lebensdauer-Thema ist damit beigelegt">
|
||||
|
|
@ -65978,7 +66019,13 @@
|
|||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1696538612261" ID="ID_661367597" MODIFIED="1696538614839" TEXT="für Variante-2"/>
|
||||
<node CREATED="1696538612261" ID="ID_661367597" MODIFIED="1696538614839" TEXT="für Variante-2">
|
||||
<node CREATED="1696933810166" ID="ID_906750178" MODIFIED="1696933829261" TEXT="stelle Storage bereit als std::function"/>
|
||||
<node CREATED="1696529718984" ID="ID_1868637331" MODIFIED="1696934476853" TEXT="die schon definierten Hooks + zusätzlichen Erweiterungspunkt">
|
||||
<arrowlink COLOR="#fdfcc6" DESTINATION="ID_1153306127" ENDARROW="Default" ENDINCLINATION="-114;10;" ID="Arrow_ID_880044186" STARTARROW="None" STARTINCLINATION="263;12;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1696690988844" ID="ID_480585061" MODIFIED="1696861459249" TEXT="das Race-Problem addressieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue