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