diff --git a/src/lib/thread.hpp b/src/lib/thread.hpp index bda68fe5b..9c7ef8f9c 100644 --- a/src/lib/thread.hpp +++ b/src/lib/thread.hpp @@ -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 ThreadLifecycle (RES (SUB::*memFun) (ARGS...), ARGS ...args) - : ThreadLifecycle{util::joinDash (typeStr(), args...) + : ThreadLifecycle{util::joinDash (typeSymbol(), args...) ,std::move (memFun) ,static_cast (this) ,forward (args)... } diff --git a/tests/library/thread-wrapper-join-test.cpp b/tests/library/thread-wrapper-join-test.cpp index 1ba9acd68..015510fc8 100644 --- a/tests/library/thread-wrapper-join-test.cpp +++ b/tests/library/thread-wrapper-join-test.cpp @@ -27,35 +27,37 @@ #include "lib/test/run.hpp" #include "lib/test/test-helper.hpp" - #include "lib/thread.hpp" #include "lib/error.hpp" -#include +#include -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() } /***********************************************************************//** - * @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"_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() ); } }; diff --git a/tests/library/thread-wrapper-test.cpp b/tests/library/thread-wrapper-test.cpp index 38ded9666..8eb8088ae 100644 --- a/tests/library/thread-wrapper-test.cpp +++ b/tests/library/thread-wrapper-test.cpp @@ -124,7 +124,7 @@ namespace test{ { uint x = rand() % 1000; globalSum += (i + x); - threads.emplace (&TestThread::doIt, uint{i}, uint{x}); + threads.emplace (&TestThread::doIt, i, x); } // Note: bind to member function, copying arguments while (explore(threads).has_any()) diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 69d813c69..5538263d1 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -79026,9 +79026,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + + @@ -79263,8 +79266,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -79949,8 +79952,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -80017,16 +80020,24 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + - + + - - + + + + + + + + +