diff --git a/src/lib/thread.hpp b/src/lib/thread.hpp index 7b81d7413..70e4ee91f 100644 --- a/src/lib/thread.hpp +++ b/src/lib/thread.hpp @@ -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 + struct PolicyLifecycleHook + : PolicyLaunchOnly + { + using BasePol = PolicyLaunchOnly; + using BasePol::BasePol; + + using Hook = function; + + Hook hook_beginThread{}; + Hook hook_afterThread{}; + Hook hook_looseThread{}; + + TAR& + castInstance() + { + return static_cast( + static_cast (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 + Launch&& + atStart (HOOK&& hook) + { + return addHook (&Policy::hook_beginThread, forward (hook)); + } + + template + Launch&& + atEnd (HOOK&& hook) + { + return addHook (&Policy::hook_afterThread, forward (hook)); + } + + template + Launch&& + onOrphan (HOOK&& hook) + { + return addHook (&Policy::hook_looseThread, forward (hook)); + } + + private: + template + Launch&& + addHook (FUN Policy::*storedHook, HOOK&& hook) + { + return addLayer ([storedHook, hook = forward(hook)] + (ThreadLifecycle& wrapper) + { + wrapper.*storedHook = move (hook); + chain (wrapper); + }); + } + Launch&& addLayer (Act action) { diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 4b7625c9c..056657e52 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -65206,6 +65206,7 @@ + @@ -65310,6 +65311,26 @@ + + + + + + + + + + + + + +

+ ...und wir wären aus der Nummer raus: das ist nämlich oberhalb der protected inheritance +

+ +
+
+
@@ -65326,8 +65347,8 @@ - - + + @@ -65350,8 +65371,7 @@ - - + @@ -65360,7 +65380,28 @@

- + +
+ + + +
+ + + + + + + + + + + + + + + + @@ -65978,7 +66019,13 @@ - + + + + + + +