]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/30_threads/try_lock/4.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 30_threads / try_lock / 4.cc
1 // { dg-do run }
2 // { dg-additional-options "-pthread" { target pthread } }
3 // { dg-require-effective-target c++11 }
4 // { dg-require-gthreads "" }
5
6 // Copyright (C) 2010-2021 Free Software Foundation, Inc.
7 //
8 // This file is part of the GNU ISO C++ Library. This library is free
9 // software; you can redistribute it and/or modify it under the
10 // terms of the GNU General Public License as published by the
11 // Free Software Foundation; either version 3, or (at your option)
12 // any later version.
13
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18
19 // You should have received a copy of the GNU General Public License along
20 // with this library; see the file COPYING3. If not see
21 // <http://www.gnu.org/licenses/>.
22
23
24 #include <mutex>
25 #include <testsuite_hooks.h>
26
27 struct unreliable_lock
28 {
29 std::mutex m;
30 std::unique_lock<std::mutex> l;
31
32 static int count;
33 static int throw_on;
34 static int lock_on;
35
36 unreliable_lock() : l(m, std::defer_lock) { }
37
38 ~unreliable_lock()
39 {
40 VERIFY( !l.owns_lock() );
41 }
42
43 void lock()
44 {
45 if (count == throw_on)
46 throw throw_on;
47 ++count;
48 l.lock();
49 }
50 bool try_lock()
51 {
52 if (count == throw_on)
53 throw throw_on;
54 std::unique_lock<std::mutex> l2(m, std::defer_lock);
55 if (count == lock_on)
56 l2.lock();
57 ++count;
58 return l.try_lock();
59 }
60
61 void unlock()
62 {
63 VERIFY( l.owns_lock() );
64 l.unlock();
65 }
66
67 };
68
69 int unreliable_lock::count = 0;
70 int unreliable_lock::throw_on = -1;
71 int unreliable_lock::lock_on = -1;
72
73 void test01()
74 {
75 unreliable_lock l1, l2, l3;
76
77 try
78 {
79 unreliable_lock::count = 0;
80 int result = std::try_lock(l1, l2, l3);
81 VERIFY( result == -1 );
82 VERIFY( unreliable_lock::count == 3 );
83 l1.unlock();
84 l2.unlock();
85 l3.unlock();
86 }
87 catch (...)
88 {
89 VERIFY( false );
90 }
91 }
92
93 void test02()
94 {
95 unreliable_lock l1, l2, l3;
96
97 try
98 {
99 // test behaviour when a lock is already held
100 unreliable_lock::lock_on = 0;
101 while (unreliable_lock::lock_on < 3)
102 {
103 unreliable_lock::count = 0;
104 int failed = std::try_lock(l1, l2, l3);
105 VERIFY( failed == unreliable_lock::lock_on );
106 ++unreliable_lock::lock_on;
107 }
108 }
109 catch (...)
110 {
111 VERIFY( false );
112 }
113 }
114
115 void test03()
116 {
117 unreliable_lock l1, l2, l3;
118
119 try
120 {
121 // test behaviour when an exception is thrown
122 unreliable_lock::throw_on = 0;
123 while (unreliable_lock::throw_on < 3)
124 {
125 unreliable_lock::count = 0;
126 try
127 {
128 std::try_lock(l1, l2, l3);
129 VERIFY( false );
130 }
131 catch (int e)
132 {
133 VERIFY( e == unreliable_lock::throw_on );
134 }
135 ++unreliable_lock::throw_on;
136 }
137 }
138 catch (...)
139 {
140 VERIFY( false );
141 }
142 }
143
144 int main()
145 {
146 test01();
147 test02();
148 test03();
149 return 0;
150 }