libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

PR30202_notify_from_pthread_created_thread.pass.cpp (1959B)


      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: https://bugs.llvm.org/show_bug.cgi?id=30202
     24 
     25 
     26 #include <condition_variable>
     27 #include <mutex>
     28 #include <thread>
     29 #include <chrono>
     30 #include <cassert>
     31 #include <pthread.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 
     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 
     49 int 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 }