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// ADDITIONAL_COMPILE_FLAGS(gcc-style-warnings): -Wno-self-move
13
14// jthread& operator=(jthread&&) noexcept;
15
16#include <atomic>
17#include <cassert>
18#include <concepts>
19#include <stop_token>
20#include <thread>
21#include <type_traits>
22#include <utility>
23#include <vector>
24
25#include "make_test_thread.h"
26#include "test_macros.h"
27
28static_assert(std::is_nothrow_move_assignable_v<std::jthread>);
29
30int main(int, char**) {
31 // If &x == this is true, there are no effects.
32 {
33 std::jthread j = support::make_test_jthread([] {});
34 auto id = j.get_id();
35 auto ssource = j.get_stop_source();
36 j = std::move(j);
37 assert(j.get_id() == id);
38 assert(j.get_stop_source() == ssource);
39 }
40
41 // if joinable() is true, calls request_stop() and then join()
42 // request_stop is called
43 {
44 std::jthread j1 = support::make_test_jthread([] {});
45 bool called = false;
46 std::stop_callback cb(j1.get_stop_token(), [&called] { called = true; });
47
48 std::jthread j2 = support::make_test_jthread([] {});
49 j1 = std::move(j2);
50 assert(called);
51 }
52
53 // if joinable() is true, calls request_stop() and then join()
54 // join is called
55 {
56 std::atomic_int calledTimes = 0;
57 std::vector<std::jthread> jts;
58 constexpr auto numberOfThreads = 10u;
59 jts.reserve(numberOfThreads);
60 for (auto i = 0u; i < numberOfThreads; ++i) {
61 jts.emplace_back(support::make_test_jthread([&] {
62 std::this_thread::sleep_for(std::chrono::milliseconds(2));
63 calledTimes.fetch_add(1, std::memory_order_relaxed);
64 }));
65 }
66
67 for (auto i = 0u; i < numberOfThreads; ++i) {
68 jts[i] = std::jthread{};
69 }
70
71 // If join was called as expected, calledTimes must equal to numberOfThreads
72 // If join was not called, there is a chance that the check below happened
73 // before test threads incrementing the counter, thus calledTimed would
74 // be less than numberOfThreads.
75 // This is not going to catch issues 100%. Creating more threads to increase
76 // the probability of catching the issue
77 assert(calledTimes.load(std::memory_order_relaxed) == numberOfThreads);
78 }
79
80 // then assigns the state of x to *this
81 {
82 std::jthread j1 = support::make_test_jthread([] {});
83 std::jthread j2 = support::make_test_jthread([] {});
84 auto id2 = j2.get_id();
85 auto ssource2 = j2.get_stop_source();
86
87 j1 = std::move(j2);
88
89 assert(j1.get_id() == id2);
90 assert(j1.get_stop_source() == ssource2);
91 }
92
93 // sets x to a default constructed state
94 {
95 std::jthread j1 = support::make_test_jthread([] {});
96 std::jthread j2 = support::make_test_jthread([] {});
97 j1 = std::move(j2);
98
99 assert(j2.get_id() == std::jthread::id());
100 assert(!j2.get_stop_source().stop_possible());
101 }
102
103 // joinable is false
104 {
105 std::jthread j1;
106 std::jthread j2 = support::make_test_jthread([] {});
107
108 auto j2Id = j2.get_id();
109
110 j1 = std::move(j2);
111
112 assert(j1.get_id() == j2Id);
113 }
114
115 return 0;
116}
117

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of libcxx/test/std/thread/thread.jthread/assign.move.pass.cpp