Library: complete and modernise ThreadWrapperJoin_test

Since the decision was taken to retain support for this special feature,
and even extend it to allow passing values, the additional functionality
should be documented in the test. Doing so also highlighted subtle problems
with argument binding.
This commit is contained in:
Fischlurch 2023-09-29 21:38:22 +02:00
parent 1512e017e1
commit 1d625a01e0
4 changed files with 90 additions and 50 deletions

View file

@ -127,7 +127,7 @@ namespace lib {
namespace thread {// Thread-wrapper base implementation...
using lib::meta::typeStr;
using lib::meta::typeSymbol;
using std::forward;
using std::decay_t;
using std::invoke_result_t;
@ -313,7 +313,7 @@ namespace lib {
template<class SUB, typename...ARGS>
ThreadLifecycle (RES (SUB::*memFun) (ARGS...), ARGS ...args)
: ThreadLifecycle{util::joinDash (typeStr<SUB>(), args...)
: ThreadLifecycle{util::joinDash (typeSymbol<SUB>(), args...)
,std::move (memFun)
,static_cast<SUB*> (this)
,forward<ARGS> (args)... }

View file

@ -27,35 +27,37 @@
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/thread.hpp"
#include "lib/error.hpp"
#include <functional>
#include <chrono>
using std::bind;
using test::Test;
using std::this_thread::sleep_for;
using namespace std::chrono_literals;
namespace lib {
namespace test {
using lumiera::error::LUMIERA_ERROR_LOGIC;
using error::LUMIERA_ERROR_LOGIC;
namespace {
const int DESTRUCTION_CODE = 23;
const int DESTRUCTION_CODE = -23;
LUMIERA_ERROR_DEFINE(SPECIAL, "grandiose exception");
LUMIERA_ERROR_DEFINE(SPECIAL, "007 exception");
#define Type(_EXPR_) lib::test::showType<decltype(_EXPR_)>()
}
/***********************************************************************//**
* @test use the Lumiera Vault to create some new threads, additionally
* synchronising with these child threads and waiting for termination.
*
* @see vault::Thread
* @see threads.h
* @test verify the special flavour of the thread-wrapper, allowing to block
* waiting on thread end and then pass result or error state.
* @see thread.hpp
* @see Result_test
* @see ThreadWrapper_test
* @see SyncLocking_test
*/
class ThreadWrapperJoin_test : public Test
{
@ -63,52 +65,79 @@ namespace test {
virtual void
run (Arg)
{
simpleUse ();
wrongUse ();
simpleUse();
returnValue();
detectFailure();
joinOnceOnly();
}
volatile int aValue_; ///< state to be modified by the other thread
void
simpleUse()
{
ThreadJoinable theThread{"test join-1"
,[]{ sleep_for (10ms); }};
CHECK (theThread);
theThread.join(); // blocks until thread-function has terminated
CHECK (not theThread);
}
int
theAction (int secretValue) ///< to be run in a new thread...
{
usleep (100000); // pause 100ms prior to modifying
sleep_for (100ms); // pause 100ms prior to modifying
if (DESTRUCTION_CODE == secretValue)
LUMIERA_ERROR_SET(test, SPECIAL, 0);
throw error::External{"special agent detected"
, LUMIERA_ERROR_SPECIAL};
else
aValue_ = secretValue+42;
return secretValue+42;
}
void
simpleUse ()
returnValue()
{
aValue_=0;
int mySecret = (rand() % 1000) - 500;
int mySecret = rand() % 1000;
ThreadJoinable newThread("test Thread joining-1"
, bind (&ThreadWrapperJoin_test::theAction, this, mySecret)
);
newThread.join(); // blocks until theAction() is done
CHECK (aValue_ == mySecret+42);
ThreadJoinable theThread{"test join-2"
,&ThreadWrapperJoin_test::theAction
, this, mySecret};
// Note: join() passes the result value captured in the thread
CHECK (mySecret+42 == theThread.join());
}
void
wrongUse ()
detectFailure()
{
ThreadJoinable newThread("test Thread joining-2"
, bind (&ThreadWrapperJoin_test::theAction, this, 1234)
);
newThread.join(); // blocks until theAction() is done
ThreadJoinable theThread{"test join-3"
,&ThreadWrapperJoin_test::theAction
, this, DESTRUCTION_CODE};
// join() actually returns a proxy...
auto res = theThread.join();
CHECK (Type(res) == "Result<int>"_expect);
VERIFY_ERROR(LOGIC, newThread.join() );
VERIFY_ERROR(LOGIC, newThread.join() );
// can detect that the thread was aborted with an exception
CHECK (not res.isValid());
VERIFY_ERROR(SPECIAL, res.maybeThrow() );
VERIFY_ERROR(SPECIAL, (int)res );
}
void
joinOnceOnly ()
{
ThreadJoinable theThread{"joining-4"
,[]{ sleep_for (10ms); }};
theThread.join();
VERIFY_ERROR(LOGIC, theThread.join() );
VERIFY_ERROR(LOGIC, theThread.join() );
}
};

View file

@ -124,7 +124,7 @@ namespace test{
{
uint x = rand() % 1000;
globalSum += (i + x);
threads.emplace<TestThread> (&TestThread::doIt, uint{i}, uint{x});
threads.emplace<TestThread> (&TestThread::doIt, i, x);
} // Note: bind to member function, copying arguments
while (explore(threads).has_any())

View file

@ -79026,9 +79026,12 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1695392987999" ID="ID_109089425" MODIFIED="1695393002077" TEXT="wird (derzeit und absehbar) nur f&#xfc;r Tests verwendet">
<icon BUILTIN="info"/>
<node CREATED="1695393029161" ID="ID_1726147640" MODIFIED="1695393053763" TEXT="und daf&#xfc;r ist auch die Fehler-Weitergabe sinnvoll"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1695393054345" ID="ID_582803458" MODIFIED="1695393067033" TEXT="also auch dieses Zusatz-Feature erhalten">
<node COLOR="#435e98" CREATED="1695393054345" ID="ID_582803458" MODIFIED="1696015399487" TEXT="also auch dieses Zusatz-Feature erhalten">
<icon BUILTIN="yes"/>
</node>
<node COLOR="#435e98" CREATED="1696015411959" ID="ID_399469746" MODIFIED="1696015426502" TEXT="ausgebaut: kann nun sogar Ergebniswert transportieren">
<icon BUILTIN="idea"/>
</node>
</node>
</node>
<node CREATED="1695313818614" ID="ID_470584516" MODIFIED="1695313837839" TEXT="Thread::syncPoint() / sync()">
@ -79263,8 +79266,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1695394188133" ID="ID_1229328590" MODIFIED="1695394203632" TEXT="Umbau">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1695394188133" ID="ID_1229328590" MODIFIED="1696015383325" TEXT="Umbau">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1695597011139" ID="ID_125138411" MODIFIED="1695859127749" TEXT="Kopie des bestehenden Thread-Wrappers umschreiben">
<linktarget COLOR="#6ebe5a" DESTINATION="ID_125138411" ENDARROW="Default" ENDINCLINATION="43;-18;" ID="Arrow_ID_195305087" SOURCE="ID_215388471" STARTARROW="None" STARTINCLINATION="-113;6;"/>
<icon BUILTIN="button_ok"/>
@ -79949,8 +79952,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1695394205547" ID="ID_1719816317" MODIFIED="1695394259544" TEXT="Tests umstellen und modernisieren">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1695394205547" ID="ID_1719816317" MODIFIED="1696015377362" TEXT="Tests umstellen und modernisieren">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1695394270093" ID="ID_585437655" MODIFIED="1696007768225" TEXT="ThreadWrapper_test">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1695911786871" ID="ID_1371513124" MODIFIED="1695911794232" TEXT="l&#xe4;uft nach Umstellung">
@ -80017,16 +80020,24 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1695394665822" ID="ID_881973960" MODIFIED="1695394668399" TEXT="ThreadWrapperJoin_test">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1695394665822" ID="ID_881973960" MODIFIED="1696015353416" TEXT="ThreadWrapperJoin_test">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1695911786871" ID="ID_1004221223" MODIFIED="1695911801372" TEXT="l&#xe4;uft nach Umstellung">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1695394703974" ID="ID_1918931115" MODIFIED="1695394714328" TEXT="erscheint bereits ad&#xe4;quat">
<node COLOR="#5b280f" CREATED="1695394703974" ID="ID_1918931115" MODIFIED="1696015368741" TEXT="erscheint bereits ad&#xe4;quat">
<icon BUILTIN="yes"/>
<icon BUILTIN="button_cancel"/>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1695394715296" ID="ID_1135505355" MODIFIED="1695394724096" TEXT="pr&#xfc;fen: ggfs Fehlercode durchgeben?">
<icon BUILTIN="help"/>
<node COLOR="#338800" CREATED="1696009922459" ID="ID_1972276036" MODIFIED="1696015355517" TEXT="modernisieren kann man ihn trotzdem">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1696009997026" ID="ID_674091759" MODIFIED="1696015360374" TEXT="&#x3bb; binden"/>
<node COLOR="#435e98" CREATED="1696010004869" ID="ID_819043932" MODIFIED="1696015360374" TEXT="warten per chrono-Angabe"/>
</node>
<node COLOR="#338800" CREATED="1696010020799" ID="ID_698469449" MODIFIED="1696015357116" TEXT="neue Funktionalit&#xe4;t abdecken">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1696010033020" ID="ID_349091998" MODIFIED="1696015360374" TEXT="R&#xfc;ckgabewert"/>
<node COLOR="#435e98" CREATED="1696010036948" ID="ID_440877573" MODIFIED="1696015360375" TEXT="Fehlerbehandlung"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1695394744028" ID="ID_1755648327" MODIFIED="1695394746744" TEXT="ThreadWrapperSelfRecognitionTest_test">