105 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: no-threads10// UNSUPPORTED: c++03, c++1111 12// <shared_mutex>13 14// template <class Mutex> class shared_lock;15 16// explicit shared_lock(mutex_type& m);17 18// template<class _Mutex> shared_lock(shared_lock<_Mutex>)19// -> shared_lock<_Mutex>; // C++1720 21#include <atomic>22#include <cassert>23#include <shared_mutex>24#include <thread>25#include <type_traits>26#include <vector>27 28#include "make_test_thread.h"29#include "test_macros.h"30 31struct Monitor {32 bool lock_shared_called = false;33 bool unlock_shared_called = false;34};35 36struct TrackedMutex {37 Monitor* monitor = nullptr;38 39 void lock_shared() {40 if (monitor != nullptr)41 monitor->lock_shared_called = true;42 }43 void unlock_shared() {44 if (monitor != nullptr)45 monitor->unlock_shared_called = true;46 }47};48 49template <class Mutex>50void test() {51 // Basic sanity test52 {53 Mutex mutex;54 std::vector<std::thread> threads;55 std::atomic<bool> ready(false);56 for (int i = 0; i != 5; ++i) {57 threads.push_back(support::make_test_thread([&] {58 while (!ready) {59 // spin60 }61 62 std::shared_lock<Mutex> lock(mutex);63 assert(lock.owns_lock());64 }));65 }66 67 ready = true;68 for (auto& t : threads)69 t.join();70 }71 72 // Test CTAD73 {74#if TEST_STD_VER >= 1775 Mutex mutex;76 std::shared_lock lock(mutex);77 static_assert(std::is_same<decltype(lock), std::shared_lock<Mutex>>::value);78#endif79 }80}81 82int main(int, char**) {83#if TEST_STD_VER >= 1784 test<std::shared_mutex>();85#endif86 test<std::shared_timed_mutex>();87 test<TrackedMutex>();88 89 // Use shared_lock with a dummy mutex class that tracks whether each90 // operation has been called or not.91 {92 Monitor monitor;93 TrackedMutex mutex{&monitor};94 95 std::shared_lock<TrackedMutex> lock(mutex);96 assert(monitor.lock_shared_called);97 assert(lock.owns_lock());98 99 lock.unlock();100 assert(monitor.unlock_shared_called);101 }102 103 return 0;104}105