1//===----------------------------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is dual licensed under the MIT and the University of Illinois Open 6// Source Licenses. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// UNSUPPORTED: libcpp-has-no-threads 11// REQUIRES: libcpp-has-thread-api-pthread 12 13// notify_all_at_thread_exit(...) requires move semantics to transfer the 14// unique_lock. 15// UNSUPPORTED: c++98, c++03 16 17// <condition_variable> 18 19// void 20// notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); 21 22// Test that this function works with threads that were not created by 23// std::thread. See http://llvm.org/PR30202. 24 25 26#include <condition_variable> 27#include <mutex> 28#include <thread> 29#include <chrono> 30#include <cassert> 31#include <pthread.h> 32 33std::condition_variable cv; 34std::mutex mut; 35bool exited = false; 36 37typedef std::chrono::milliseconds ms; 38typedef std::chrono::high_resolution_clock Clock; 39 40void* 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 49int main() 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