Lumiera  0.pre.03
»edit your freedom«
thread-wrapper-join-test.cpp
Go to the documentation of this file.
1 /*
2  ThreadWrapperJoin(Test) - wait blocking on termination of a thread
3 
4  Copyright (C)
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
19 #include "lib/test/run.hpp"
20 #include "lib/test/test-helper.hpp"
21 #include "lib/thread.hpp"
22 #include "lib/error.hpp"
23 
24 #include <chrono>
25 
26 using test::Test;
27 using std::this_thread::sleep_for;
28 using namespace std::chrono_literals;
29 
30 
31 namespace lib {
32 namespace test {
33 
34  using error::LUMIERA_ERROR_LOGIC;
35  namespace {
36 
37  const int DESTRUCTION_CODE = -23;
38 
39  LUMIERA_ERROR_DEFINE(SPECIAL, "007 exception");
40 
41  #define Type(_EXPR_) lib::test::showType<decltype(_EXPR_)>()
42  }
43 
44 
45  /***********************************************************************/
54  {
55 
56  virtual void
57  run (Arg)
58  {
59  seedRand();
60 
61  simpleUse();
62  returnValue();
63  detectFailure();
64  joinOnceOnly();
65  }
66 
67 
68  void
69  simpleUse()
70  {
71  ThreadJoinable theThread{"test join-1"
72  ,[]{ sleep_for (10ms); }};
73  CHECK (theThread);
74  theThread.join(); // blocks until thread-function has terminated
75  CHECK (not theThread);
76  }
77 
78 
79 
80  int
81  theAction (int secretValue)
82  {
83  sleep_for (100ms); // pause 100ms prior to modifying
84 
85  if (DESTRUCTION_CODE == secretValue)
86  throw error::External{"special agent detected"
87  , LUMIERA_ERROR_SPECIAL};
88  else
89  return secretValue+42;
90  }
91 
92 
93  void
94  returnValue()
95  {
96  int mySecret = rani(1000);
97 
98  ThreadJoinable theThread{"test join-2"
99  ,&ThreadWrapperJoin_test::theAction
100  , this, mySecret};
101 
102  // Note: join() passes the result value captured in the thread
103  CHECK (mySecret+42 == theThread.join());
104  }
105 
106 
107  void
108  detectFailure()
109  {
110  ThreadJoinable theThread{"test join-3"
111  ,&ThreadWrapperJoin_test::theAction
112  , this, DESTRUCTION_CODE};
113 
114  // join() actually returns a proxy...
115  auto res = theThread.join();
116  CHECK (Type(res) == "Result<int>"_expect);
117 
118  // can detect that the thread was aborted with an exception
119  CHECK (not res.isValid());
120  VERIFY_ERROR(SPECIAL, res.maybeThrow() );
121  VERIFY_ERROR(SPECIAL, (int)res );
122  }
123 
124 
125  void
126  joinOnceOnly()
127  {
128  ThreadJoinable theThread{"test join-4"
129  ,[]{ sleep_for (10ms); }};
130  theThread.join();
131 
132  VERIFY_ERROR(LOGIC, theThread.join() );
133  VERIFY_ERROR(LOGIC, theThread.join() );
134  }
135  };
136 
137 
138 
140  LAUNCHER (ThreadWrapperJoin_test, "function common");
141 
142 
143 
144 }} // namespace lib::test
Variant of the standard case, requiring to wait and join() on the termination of this thread...
Definition: thread.hpp:668
Definition: run.hpp:40
int rani(uint bound=_iBOUND())
Definition: random.hpp:135
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
Implementation namespace for support and library code.
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:190
Abstract Base Class for all testcases.
Definition: run.hpp:53
Simplistic test class runner.
Convenience front-end to simplify and codify basic thread handling.
A collection of frequently used helper functions to support unit testing.
Lumiera error handling (C++ interface).
#define LUMIERA_ERROR_DEFINE(err, msg)
Definition and initialisation of an error constant.
Definition: error.h:71