• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // UNSUPPORTED: c++98, c++03
12 
13 // <mutex>
14 
15 // template <class ...Mutex> class lock_guard;
16 
17 // explicit lock_guard(mutex_type& m);
18 
19 // MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD
20 #define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
21 #include <mutex>
22 #include <cassert>
23 
24 #include "test_macros.h"
25 
26 struct TestMutex {
27     bool locked = false;
28     TestMutex() = default;
~TestMutexTestMutex29     ~TestMutex() { assert(!locked); }
30 
lockTestMutex31     void lock() { assert(!locked); locked = true; }
try_lockTestMutex32     bool try_lock() { if (locked) return false; locked = true; return true; }
unlockTestMutex33     void unlock() { assert(locked); locked = false; }
34 
35     TestMutex(TestMutex const&) = delete;
36     TestMutex& operator=(TestMutex const&) = delete;
37 };
38 
39 #if !defined(TEST_HAS_NO_EXCEPTIONS)
40 struct TestMutexThrows {
41     bool locked = false;
42     bool throws_on_lock = false;
43 
44     TestMutexThrows() = default;
~TestMutexThrowsTestMutexThrows45     ~TestMutexThrows() { assert(!locked); }
46 
lockTestMutexThrows47     void lock() {
48         assert(!locked);
49         if (throws_on_lock) {
50             throw 42;
51         }
52         locked = true;
53     }
54 
try_lockTestMutexThrows55     bool try_lock() {
56         if (locked) return false;
57         lock();
58         return true;
59     }
60 
unlockTestMutexThrows61     void unlock() { assert(locked); locked = false; }
62 
63     TestMutexThrows(TestMutexThrows const&) = delete;
64     TestMutexThrows& operator=(TestMutexThrows const&) = delete;
65 };
66 #endif // !defined(TEST_HAS_NO_EXCEPTIONS)
67 
main()68 int main()
69 {
70     {
71         using LG = std::lock_guard<>;
72         LG lg;
73     }
74     {
75         using LG = std::lock_guard<TestMutex, TestMutex>;
76         TestMutex m1, m2;
77         {
78             LG lg(m1, m2);
79             assert(m1.locked && m2.locked);
80         }
81         assert(!m1.locked && !m2.locked);
82     }
83     {
84         using LG = std::lock_guard<TestMutex, TestMutex, TestMutex>;
85         TestMutex m1, m2, m3;
86         {
87             LG lg(m1, m2, m3);
88             assert(m1.locked && m2.locked && m3.locked);
89         }
90         assert(!m1.locked && !m2.locked && !m3.locked);
91     }
92 #if !defined(TEST_HAS_NO_EXCEPTIONS)
93     {
94         using MT = TestMutexThrows;
95         using LG = std::lock_guard<MT, MT>;
96         MT m1, m2;
97         m1.throws_on_lock = true;
98         try {
99             LG lg(m1, m2);
100             assert(false);
101         } catch (int) {}
102         assert(!m1.locked && !m2.locked);
103     }
104     {
105         using MT = TestMutexThrows;
106         using LG = std::lock_guard<MT, MT, MT>;
107         MT m1, m2, m3;
108         m2.throws_on_lock = true;
109         try {
110             LG lg(m1, m2, m3);
111             assert(false);
112         } catch (int) {}
113         assert(!m1.locked && !m2.locked && !m3.locked);
114     }
115 #endif
116 }
117