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