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) Lumiera.org
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
28 #include "lib/test/run.hpp"
29 #include "lib/test/test-helper.hpp"
30 #include "lib/thread.hpp"
31 #include "lib/error.hpp"
32 
33 #include <chrono>
34 
35 using test::Test;
36 using std::this_thread::sleep_for;
37 using namespace std::chrono_literals;
38 
39 
40 namespace lib {
41 namespace test {
42 
43  using error::LUMIERA_ERROR_LOGIC;
44  namespace {
45 
46  const int DESTRUCTION_CODE = -23;
47 
48  LUMIERA_ERROR_DEFINE(SPECIAL, "007 exception");
49 
50  #define Type(_EXPR_) lib::test::showType<decltype(_EXPR_)>()
51  }
52 
53 
54  /***********************************************************************/
63  {
64 
65  virtual void
66  run (Arg)
67  {
68  simpleUse();
69  returnValue();
70  detectFailure();
71  joinOnceOnly();
72  }
73 
74 
75  void
76  simpleUse()
77  {
78  ThreadJoinable theThread{"test join-1"
79  ,[]{ sleep_for (10ms); }};
80  CHECK (theThread);
81  theThread.join(); // blocks until thread-function has terminated
82  CHECK (not theThread);
83  }
84 
85 
86 
87  int
88  theAction (int secretValue)
89  {
90  sleep_for (100ms); // pause 100ms prior to modifying
91 
92  if (DESTRUCTION_CODE == secretValue)
93  throw error::External{"special agent detected"
94  , LUMIERA_ERROR_SPECIAL};
95  else
96  return secretValue+42;
97  }
98 
99 
100  void
101  returnValue()
102  {
103  int mySecret = rand() % 1000;
104 
105  ThreadJoinable theThread{"test join-2"
106  ,&ThreadWrapperJoin_test::theAction
107  , this, mySecret};
108 
109  // Note: join() passes the result value captured in the thread
110  CHECK (mySecret+42 == theThread.join());
111  }
112 
113 
114  void
115  detectFailure()
116  {
117  ThreadJoinable theThread{"test join-3"
118  ,&ThreadWrapperJoin_test::theAction
119  , this, DESTRUCTION_CODE};
120 
121  // join() actually returns a proxy...
122  auto res = theThread.join();
123  CHECK (Type(res) == "Result<int>"_expect);
124 
125  // can detect that the thread was aborted with an exception
126  CHECK (not res.isValid());
127  VERIFY_ERROR(SPECIAL, res.maybeThrow() );
128  VERIFY_ERROR(SPECIAL, (int)res );
129  }
130 
131 
132  void
133  joinOnceOnly ()
134  {
135  ThreadJoinable theThread{"joining-4"
136  ,[]{ sleep_for (10ms); }};
137  theThread.join();
138 
139  VERIFY_ERROR(LOGIC, theThread.join() );
140  VERIFY_ERROR(LOGIC, theThread.join() );
141  }
142  };
143 
144 
145 
147  LAUNCHER (ThreadWrapperJoin_test, "function common");
148 
149 
150 
151 }} // namespace lib::test
Variant of the standard case, requiring to wait and join() on the termination of this thread...
Definition: thread.hpp:676
Definition: run.hpp:49
#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:199
Abstract Base Class for all testcases.
Definition: run.hpp:62
Simple 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:80