blob: 7fbdcaf7290a42db05d0f0d6d0031a27c2173d1f [file] [log] [blame]
onqtamc9b4e1f2018-08-17 14:20:59 +03001#include "doctest.h"
2
onqtam65cf6922018-08-20 11:29:33 +03003#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
4
onqtamc9b4e1f2018-08-17 14:20:59 +03005DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
6#include <thread>
onqtama2e77c72018-08-20 11:05:05 +03007#include <mutex>
8#include <exception>
9#include <stdexcept>
onqtamc9b4e1f2018-08-17 14:20:59 +030010DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END
11
onqtamc9b4e1f2018-08-17 14:20:59 +030012TEST_CASE("threads...") {
onqtama2e77c72018-08-20 11:05:05 +030013 auto call_from_thread = [](int value) {
14 INFO("print me!");
15 // one of these has to fail
16 CHECK(value == 1);
17 CHECK(value == 2);
18 };
19
20 int data_1 = 1;
21 int data_2 = 2;
22 CAPTURE(data_1); // will not be used for assertions in other threads
23
24 // subcases have to be used only in the main thread (where the test runner is)
25 SUBCASE("test runner thread") {
26 call_from_thread(data_1);
27 }
28
29 // normal threads which are assumed not to throw
30 SUBCASE("spawned threads") {
31 std::thread t1(call_from_thread, data_1);
32 std::thread t2(call_from_thread, data_2);
33
34 t1.join();
35 t2.join();
36 }
37
38 // exceptions from threads (that includes failing REQUIRE asserts) have to be handled explicitly
39 SUBCASE("spawned threads with exception propagation") {
onqtam8f100442018-08-20 11:53:10 +030040 std::exception_ptr exception_ptr = nullptr;
41 std::mutex mutex;
42
43 auto might_throw = [&]() {
onqtama2e77c72018-08-20 11:05:05 +030044 try {
45 REQUIRE(1 == 1);
46 REQUIRE(1 == 2); // will fail and throw an exception
47 MESSAGE("not reached!");
48 } catch(...) {
onqtam8f100442018-08-20 11:53:10 +030049 // make sure there are no races when dealing with the exception ptr
50 std::lock_guard<std::mutex> lock(mutex);
onqtama2e77c72018-08-20 11:05:05 +030051
onqtam8f100442018-08-20 11:53:10 +030052 // set the exception pointer in case of an exception - might overwrite
onqtama2e77c72018-08-20 11:05:05 +030053 // another exception but here we care about propagating any exception - not all
onqtam8f100442018-08-20 11:53:10 +030054 exception_ptr = std::current_exception();
onqtama2e77c72018-08-20 11:05:05 +030055 }
56 };
57 std::thread t1(might_throw);
58 std::thread t2(might_throw);
59
60 t1.join();
61 t2.join();
62
63 // if any thread has thrown an exception - rethrow it
onqtam8f100442018-08-20 11:53:10 +030064 if(exception_ptr)
65 std::rethrow_exception(exception_ptr);
onqtama2e77c72018-08-20 11:05:05 +030066 }
onqtamc9b4e1f2018-08-17 14:20:59 +030067}
onqtam65cf6922018-08-20 11:29:33 +030068
69#endif // DOCTEST_CONFIG_NO_EXCEPTIONS