xref: /llvm-project/libcxx/test/std/thread/thread.mutex/thread.lock.algorithm/lock.pass.cpp (revision 76e316f995f8970075e93c4888cbe0436363137a)
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 // XFAIL: libcpp-no-exceptions
11 // UNSUPPORTED: libcpp-has-no-threads
12 
13 // This test hangs forever when built against libstdc++. In order to allow
14 // validation of the test suite against other STLs we have to mark it
15 // unsupported.
16 // UNSUPPORTED: libstdc++
17 
18 // <mutex>
19 
20 // template <class L1, class L2, class... L3>
21 //   void lock(L1&, L2&, L3&...);
22 
23 #include <mutex>
24 #include <cassert>
25 
26 class L0
27 {
28     bool locked_;
29 
30 public:
31     L0() : locked_(false) {}
32 
33     void lock()
34     {
35         locked_ = true;
36     }
37 
38     bool try_lock()
39     {
40         locked_ = true;
41         return locked_;
42     }
43 
44     void unlock() {locked_ = false;}
45 
46     bool locked() const {return locked_;}
47 };
48 
49 class L1
50 {
51     bool locked_;
52 
53 public:
54     L1() : locked_(false) {}
55 
56     void lock()
57     {
58         locked_ = true;
59     }
60 
61     bool try_lock()
62     {
63         locked_ = false;
64         return locked_;
65     }
66 
67     void unlock() {locked_ = false;}
68 
69     bool locked() const {return locked_;}
70 };
71 
72 class L2
73 {
74     bool locked_;
75 
76 public:
77     L2() : locked_(false) {}
78 
79     void lock()
80     {
81         throw 1;
82     }
83 
84     bool try_lock()
85     {
86         throw 1;
87         return locked_;
88     }
89 
90     void unlock() {locked_ = false;}
91 
92     bool locked() const {return locked_;}
93 };
94 
95 int main()
96 {
97     {
98         L0 l0;
99         L0 l1;
100         std::lock(l0, l1);
101         assert(l0.locked());
102         assert(l1.locked());
103     }
104     {
105         L0 l0;
106         L1 l1;
107         std::lock(l0, l1);
108         assert(l0.locked());
109         assert(l1.locked());
110     }
111     {
112         L1 l0;
113         L0 l1;
114         std::lock(l0, l1);
115         assert(l0.locked());
116         assert(l1.locked());
117     }
118     {
119         L0 l0;
120         L2 l1;
121         try
122         {
123             std::lock(l0, l1);
124             assert(false);
125         }
126         catch (int)
127         {
128             assert(!l0.locked());
129             assert(!l1.locked());
130         }
131     }
132     {
133         L2 l0;
134         L0 l1;
135         try
136         {
137             std::lock(l0, l1);
138             assert(false);
139         }
140         catch (int)
141         {
142             assert(!l0.locked());
143             assert(!l1.locked());
144         }
145     }
146     {
147         L1 l0;
148         L2 l1;
149         try
150         {
151             std::lock(l0, l1);
152             assert(false);
153         }
154         catch (int)
155         {
156             assert(!l0.locked());
157             assert(!l1.locked());
158         }
159     }
160     {
161         L2 l0;
162         L1 l1;
163         try
164         {
165             std::lock(l0, l1);
166             assert(false);
167         }
168         catch (int)
169         {
170             assert(!l0.locked());
171             assert(!l1.locked());
172         }
173     }
174     {
175         L2 l0;
176         L2 l1;
177         try
178         {
179             std::lock(l0, l1);
180             assert(false);
181         }
182         catch (int)
183         {
184             assert(!l0.locked());
185             assert(!l1.locked());
186         }
187     }
188 #ifndef _LIBCPP_HAS_NO_VARIADICS
189     {
190         L0 l0;
191         L0 l1;
192         L0 l2;
193         std::lock(l0, l1, l2);
194         assert(l0.locked());
195         assert(l1.locked());
196         assert(l2.locked());
197     }
198     {
199         L2 l0;
200         L2 l1;
201         L2 l2;
202         try
203         {
204             std::lock(l0, l1, l2);
205             assert(false);
206         }
207         catch (int)
208         {
209             assert(!l0.locked());
210             assert(!l1.locked());
211             assert(!l2.locked());
212         }
213     }
214     {
215         L0 l0;
216         L0 l1;
217         L1 l2;
218         std::lock(l0, l1, l2);
219         assert(l0.locked());
220         assert(l1.locked());
221         assert(l2.locked());
222     }
223     {
224         L0 l0;
225         L1 l1;
226         L0 l2;
227         std::lock(l0, l1, l2);
228         assert(l0.locked());
229         assert(l1.locked());
230         assert(l2.locked());
231     }
232     {
233         L1 l0;
234         L0 l1;
235         L0 l2;
236         std::lock(l0, l1, l2);
237         assert(l0.locked());
238         assert(l1.locked());
239         assert(l2.locked());
240     }
241     {
242         L0 l0;
243         L0 l1;
244         L2 l2;
245         try
246         {
247             std::lock(l0, l1, l2);
248             assert(false);
249         }
250         catch (int)
251         {
252             assert(!l0.locked());
253             assert(!l1.locked());
254             assert(!l2.locked());
255         }
256     }
257     {
258         L0 l0;
259         L2 l1;
260         L0 l2;
261         try
262         {
263             std::lock(l0, l1, l2);
264             assert(false);
265         }
266         catch (int)
267         {
268             assert(!l0.locked());
269             assert(!l1.locked());
270             assert(!l2.locked());
271         }
272     }
273     {
274         L2 l0;
275         L0 l1;
276         L0 l2;
277         try
278         {
279             std::lock(l0, l1, l2);
280             assert(false);
281         }
282         catch (int)
283         {
284             assert(!l0.locked());
285             assert(!l1.locked());
286             assert(!l2.locked());
287         }
288     }
289     {
290         L2 l0;
291         L2 l1;
292         L0 l2;
293         try
294         {
295             std::lock(l0, l1, l2);
296             assert(false);
297         }
298         catch (int)
299         {
300             assert(!l0.locked());
301             assert(!l1.locked());
302             assert(!l2.locked());
303         }
304     }
305     {
306         L2 l0;
307         L0 l1;
308         L2 l2;
309         try
310         {
311             std::lock(l0, l1, l2);
312             assert(false);
313         }
314         catch (int)
315         {
316             assert(!l0.locked());
317             assert(!l1.locked());
318             assert(!l2.locked());
319         }
320     }
321     {
322         L0 l0;
323         L2 l1;
324         L2 l2;
325         try
326         {
327             std::lock(l0, l1, l2);
328             assert(false);
329         }
330         catch (int)
331         {
332             assert(!l0.locked());
333             assert(!l1.locked());
334             assert(!l2.locked());
335         }
336     }
337     {
338         L2 l0;
339         L2 l1;
340         L1 l2;
341         try
342         {
343             std::lock(l0, l1, l2);
344             assert(false);
345         }
346         catch (int)
347         {
348             assert(!l0.locked());
349             assert(!l1.locked());
350             assert(!l2.locked());
351         }
352     }
353     {
354         L2 l0;
355         L1 l1;
356         L2 l2;
357         try
358         {
359             std::lock(l0, l1, l2);
360             assert(false);
361         }
362         catch (int)
363         {
364             assert(!l0.locked());
365             assert(!l1.locked());
366             assert(!l2.locked());
367         }
368     }
369     {
370         L1 l0;
371         L2 l1;
372         L2 l2;
373         try
374         {
375             std::lock(l0, l1, l2);
376             assert(false);
377         }
378         catch (int)
379         {
380             assert(!l0.locked());
381             assert(!l1.locked());
382             assert(!l2.locked());
383         }
384     }
385     {
386         L0 l0;
387         L0 l1;
388         L0 l2;
389         L0 l3;
390         std::lock(l0, l1, l2, l3);
391         assert(l0.locked());
392         assert(l1.locked());
393         assert(l2.locked());
394         assert(l3.locked());
395     }
396     {
397         L0 l0;
398         L0 l1;
399         L0 l2;
400         L1 l3;
401         std::lock(l0, l1, l2, l3);
402         assert(l0.locked());
403         assert(l1.locked());
404         assert(l2.locked());
405         assert(l3.locked());
406     }
407     {
408         L0 l0;
409         L0 l1;
410         L1 l2;
411         L0 l3;
412         std::lock(l0, l1, l2, l3);
413         assert(l0.locked());
414         assert(l1.locked());
415         assert(l2.locked());
416         assert(l3.locked());
417     }
418     {
419         L0 l0;
420         L1 l1;
421         L0 l2;
422         L0 l3;
423         std::lock(l0, l1, l2, l3);
424         assert(l0.locked());
425         assert(l1.locked());
426         assert(l2.locked());
427         assert(l3.locked());
428     }
429     {
430         L1 l0;
431         L0 l1;
432         L0 l2;
433         L0 l3;
434         std::lock(l0, l1, l2, l3);
435         assert(l0.locked());
436         assert(l1.locked());
437         assert(l2.locked());
438         assert(l3.locked());
439     }
440     {
441         L0 l0;
442         L0 l1;
443         L0 l2;
444         L2 l3;
445         try
446         {
447             std::lock(l0, l1, l2, l3);
448             assert(false);
449         }
450         catch (int)
451         {
452             assert(!l0.locked());
453             assert(!l1.locked());
454             assert(!l2.locked());
455             assert(!l3.locked());
456         }
457     }
458     {
459         L0 l0;
460         L0 l1;
461         L2 l2;
462         L0 l3;
463         try
464         {
465             std::lock(l0, l1, l2, l3);
466             assert(false);
467         }
468         catch (int)
469         {
470             assert(!l0.locked());
471             assert(!l1.locked());
472             assert(!l2.locked());
473             assert(!l3.locked());
474         }
475     }
476     {
477         L0 l0;
478         L2 l1;
479         L0 l2;
480         L0 l3;
481         try
482         {
483             std::lock(l0, l1, l2, l3);
484             assert(false);
485         }
486         catch (int)
487         {
488             assert(!l0.locked());
489             assert(!l1.locked());
490             assert(!l2.locked());
491             assert(!l3.locked());
492         }
493     }
494     {
495         L2 l0;
496         L0 l1;
497         L0 l2;
498         L0 l3;
499         try
500         {
501             std::lock(l0, l1, l2, l3);
502             assert(false);
503         }
504         catch (int)
505         {
506             assert(!l0.locked());
507             assert(!l1.locked());
508             assert(!l2.locked());
509             assert(!l3.locked());
510         }
511     }
512 #endif  // _LIBCPP_HAS_NO_VARIADICS
513 }
514