xref: /llvm-project/libcxx/test/std/thread/thread.jthread/dtor.pass.cpp (revision 121ed5c1985356436d0040dbe81bca26992b1fae)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // UNSUPPORTED: no-threads
10 // UNSUPPORTED: c++03, c++11, c++14, c++17
11 // XFAIL: availability-synchronization_library-missing
12 
13 // ~jthread();
14 
15 #include <atomic>
16 #include <cassert>
17 #include <optional>
18 #include <stop_token>
19 #include <thread>
20 #include <type_traits>
21 #include <vector>
22 
23 #include "make_test_thread.h"
24 #include "test_macros.h"
25 
26 int main(int, char**) {
27   // !joinable()
28   {
29     std::jthread jt;
30     assert(!jt.joinable());
31   }
32 
33   // If joinable() is true, calls request_stop() and then join().
34   // request_stop is called
35   {
36     std::optional<std::jthread> jt = support::make_test_jthread([] {});
37     bool called                    = false;
38     std::stop_callback cb(jt->get_stop_token(), [&called] { called = true; });
39     jt.reset();
40     assert(called);
41   }
42 
43   // If joinable() is true, calls request_stop() and then join().
44   // join is called
45   {
46     std::atomic_int calledTimes = 0;
47     std::vector<std::jthread> jts;
48 
49     constexpr auto numberOfThreads = 10u;
50     jts.reserve(numberOfThreads);
51     for (auto i = 0u; i < numberOfThreads; ++i) {
52       jts.emplace_back(support::make_test_jthread([&calledTimes] {
53         std::this_thread::sleep_for(std::chrono::milliseconds{2});
54         calledTimes.fetch_add(1, std::memory_order_relaxed);
55       }));
56     }
57     jts.clear();
58 
59     // If join was called as expected, calledTimes must equal to numberOfThreads
60     // If join was not called, there is a chance that the check below happened
61     // before test threads incrementing the counter, thus calledTimed would
62     // be less than numberOfThreads.
63     // This is not going to catch issues 100%. Creating more threads would increase
64     // the probability of catching the issue
65     assert(calledTimes.load(std::memory_order_relaxed) == numberOfThreads);
66   }
67 
68   return 0;
69 }
70