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: libcpp-has-no-threads
10 
11 // <thread>
12 
13 // class thread
14 
15 // void detach();
16 
17 #include <thread>
18 #include <atomic>
19 #include <system_error>
20 #include <cassert>
21 
22 #include "test_macros.h"
23 
24 std::atomic_bool done(false);
25 
26 class G
27 {
28     int alive_;
29     bool done_;
30 public:
31     static int n_alive;
32     static bool op_run;
33 
34     G() : alive_(1), done_(false)
35     {
36         ++n_alive;
37     }
38 
39     G(const G& g) : alive_(g.alive_), done_(false)
40     {
41         ++n_alive;
42     }
43     ~G()
44     {
45         alive_ = 0;
46         --n_alive;
47         if (done_) done = true;
48     }
49 
50     void operator()()
51     {
52         assert(alive_ == 1);
53         assert(n_alive >= 1);
54         op_run = true;
55         done_ = true;
56     }
57 };
58 
59 int G::n_alive = 0;
60 bool G::op_run = false;
61 
62 void foo() {}
63 
64 int main(int, char**)
65 {
66     {
67         G g;
68         std::thread t0(g);
69         assert(t0.joinable());
70         t0.detach();
71         assert(!t0.joinable());
72         while (!done) {}
73         assert(G::op_run);
74         assert(G::n_alive == 1);
75     }
76     assert(G::n_alive == 0);
77 #ifndef TEST_HAS_NO_EXCEPTIONS
78     {
79         std::thread t0(foo);
80         assert(t0.joinable());
81         t0.detach();
82         assert(!t0.joinable());
83         try {
84             t0.detach();
85         } catch (std::system_error const&) {
86         }
87     }
88 #endif
89 
90   return 0;
91 }
92