diff --git a/src/lib/thread.hpp b/src/lib/thread.hpp index e136df862..12a62b6e5 100644 --- a/src/lib/thread.hpp +++ b/src/lib/thread.hpp @@ -198,7 +198,8 @@ namespace lib { void handle_end_of_thread() { - BAS::threadImpl_.detach(); + if (BAS::isLive()) + BAS::threadImpl_.detach(); } void @@ -344,6 +345,11 @@ namespace lib { public: using ThreadLifecycle::ThreadLifecycle; + + /** allow to detach explicitly — independent from thread-function's state + * @warning ensure that thread function only uses storage within its own scope + */ + void detach() { ThreadLifecycle::handle_end_of_thread(); } }; diff --git a/src/steam/control/steam-dispatcher.cpp b/src/steam/control/steam-dispatcher.cpp index 79970256c..702c71204 100644 --- a/src/steam/control/steam-dispatcher.cpp +++ b/src/steam/control/steam-dispatcher.cpp @@ -263,7 +263,8 @@ namespace control { } // leave the Session thread... // send notification of subsystem shutdown - notifyEnd (&errorMsg); + thread_.detach(); + notifyEnd (&errorMsg); // invokes ~DispatcherLoop() } void diff --git a/tests/11concurrency.tests b/tests/11concurrency.tests index a81050cb4..1a92da15e 100644 --- a/tests/11concurrency.tests +++ b/tests/11concurrency.tests @@ -17,7 +17,7 @@ return: 0 END -PLANNED "Yield-waiting sync performance" SyncBarrierPerformance_test < - - - +

es wurde von Race-Problemen berichtet, und davon, daß der zuletzt gesetzte Identifier plötzlich auf allen Threads auftaucht @@ -79463,9 +79461,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

es ergeben sich zwei Schwierigkeiten... @@ -79490,9 +79486,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

Er ist aus mehreren Gründen gut @@ -79525,9 +79519,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

das macht nur den Code komplex, macht aber die Diagnostik nicht besser; std::invoke hat bereits gute Diagnostik (man muß sie nur lesen können) @@ -80009,9 +80001,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

...indem man testet, daß eine bestimmte Berechnung stattgefunden hat @@ -80022,9 +80012,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

Da ich jetzt einen einfachsten Fall habe, kann der eigentliche Test doch wieder etwas komplexer sein... @@ -80069,9 +80057,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

### Lumiera halted due to an unexpected Error ### @@ -80099,9 +80085,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

...das ist interessant, aber nicht kritisch; und zwar weil ich den Test jetzt umgeschrieben habe auf ein Lambda, und gar keine eigenständige Klasse mehr verwende — viel spannender ist, daß der C++ - Compiler überhaupt schafft, solchen Code zu „knacken“ @@ -80517,24 +80501,21 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + - - - +

Theoretisch sollte sie sehr wohl nötig sein, da wir hier einen TypedCounter initialisieren, und das bedingt globales Locking; d.h. die weitere Initialisierung im ctor eines Threads kann durch einen anderen Thread aufgehalten werden.

- -
+
@@ -80544,7 +80525,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -80558,7 +80539,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -80569,29 +80550,23 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

...denn das sollte sich nur während der Konstruktoren auswirken, und die sind ja alle "durch", gemäß Barriere

- -
+
- - - +

dafür braucht man heutzutage nun wirklich kein Lock mehr

- -
+
@@ -80603,9 +80578,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

aber hier schläft der Dispatcher-Thrad gar nicht — sondern wartet auf das Lock @@ -80627,9 +80600,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

⟹ der Test-Controller-Thread kommt gar nicht dazu, @@ -80648,16 +80619,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

ein verschleppter Error-State

- -
+ @@ -80668,16 +80636,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

...und zwar an der einzigen Stelle, an der das zuverlässig möglich ist: im Konstruktur von Exceptions

- -
+
@@ -80719,16 +80684,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

Debugger ⟹ Lock-Guard-Destruktor wird nicht aufgerufen

- -
+
@@ -80740,32 +80702,26 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

die Exception fliegt ja aus dem Konstruktor vom Guard

- -
+
- - - +

(ja dann KANNs ja gar nicht funktionieren)

- -
+
@@ -80783,9 +80739,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

das Problem ist entstanden weil der Monitor „vorsorglich“ den Error-State auswertet, @@ -80797,79 +80751,63 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
Des weiteren ist nicht klar, was die Kopplung zwischen Exception und Error-State soll

- -
+
- - - +

die Gleichwertigkeit von Error-Flag und Exception wird nun in Frage gestellt

- -
+
- - - +

Plan: künftig sollen Error-Flags nur noch aus C-Code stammen

- -
+
- - - +

solange ich nur Detail-Komponenten gebaut habe, konnte ich von komplett definiertem Kontext (Unit-Test) ausgehen; damit waren Exceptions vor allem etwas, was man pro forma noch mit einbaut, aber letztlich nur „über die Mauer wirft“

- -
+
- - - +

die verschleppte Exception ist aber nur der Anlaß

- -
+
- - - +

der Grund ist ein Bug im Objekt-Monitor

- -
+ @@ -80883,6 +80821,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + +
@@ -80901,12 +80846,180 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - + + + + + + + + + + +

+ waitGracePeriod: Thread 'Lumiera_Session' failed to terminate after grace period. +

+ +
+ + + + + + + + + + + + + +

+ warum ist das so? +

+

+ ist das sinnvoll? +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

+ in beiden Fällen wird die Barriere als erstes aufgerufen +

+
    +
  • + im Haupt-Thread wird das Thread-Handle als Letztes konstruiert — und da gibt es die synchronizes-with - Garantie +
  • +
  • + im neuen Thread passiert außerdem nur die Konstruktion eines noch leeren Fehler-Strings — alles danach ist per try-catch gesichert +
  • +
+
+
+
+
+ + + + + + + + + + + + + +

+ SteamDispatcher ist ein Service und wird in lib::Depend gemanaged. Derartige Singletons werden zwar irgendwann in der Shutdown-Phase bereinigt, aber normalerweise treten wir erst in die Shutdown-Phase ein, nachdem allen Subsystemen zumindest ein Shutdown signalisiert wurde. +

+ +
+
+ + + + + + + + + + + + + + + +

+ ...man bekommt das nun automatisch, für die andere Lösung müßte diffiziler Code geschrieben werden, der die Gefahr bringt, den Shutdown-Vorgang insgesamt zu blocken. Oder man müßte ein »try-lock« machen mit Timeout; das ist noch gar nicht auf das API herausgeführt, wäre also noch mehr komplizierter Code. Und würde letzten Endes doch nicht verhindern können, daß genau in den problematischen Fällen der Thread nicht aufwacht/nicht reagiert und dann doch noch die Applikation terminiert wird +

+ +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -92304,9 +92417,16 @@ class Something - + + + + + + + +