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 // REQUIRES: libcpp-has-thread-api-pthread
11 
12 // notify_all_at_thread_exit(...) requires move semantics to transfer the
13 // unique_lock.
14 // UNSUPPORTED: c++03
15 
16 // <condition_variable>
17 
18 // void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
19 
20 // Test that this function works with threads that were not created by
21 // std::thread. See https://llvm.org/PR30202
22 
23 
24 #include <condition_variable>
25 #include <mutex>
26 #include <thread>
27 #include <chrono>
28 #include <cassert>
29 #include <pthread.h>
30 
31 #include "test_macros.h"
32 
33 std::condition_variable cv;
34 std::mutex mut;
35 bool exited = false;
36 
37 typedef std::chrono::milliseconds ms;
38 typedef std::chrono::high_resolution_clock Clock;
39 
func(void *)40 void* func(void*)
41 {
42     std::unique_lock<std::mutex> lk(mut);
43     std::notify_all_at_thread_exit(cv, std::move(lk));
44     std::this_thread::sleep_for(ms(300));
45     exited = true;
46     return nullptr;
47 }
48 
main(int,char **)49 int main(int, char**)
50 {
51     {
52     std::unique_lock<std::mutex> lk(mut);
53     pthread_t id;
54     int res = pthread_create(&id, 0, &func, nullptr);
55     assert(res == 0);
56     Clock::time_point t0 = Clock::now();
57     assert(exited == false);
58     cv.wait(lk);
59     Clock::time_point t1 = Clock::now();
60     assert(exited);
61     assert(t1-t0 > ms(250));
62     pthread_join(id, 0);
63     }
64     exited = false;
65     {
66     std::unique_lock<std::mutex> lk(mut);
67     std::thread t(&func, nullptr);
68     Clock::time_point t0 = Clock::now();
69     assert(exited == false);
70     cv.wait(lk);
71     Clock::time_point t1 = Clock::now();
72     assert(exited);
73     assert(t1-t0 > ms(250));
74     t.join();
75     }
76 
77   return 0;
78 }
79