1 /* Copyright (C) 2003-2022 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3 
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8 
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <https://www.gnu.org/licenses/>.  */
17 
18 #include <errno.h>
19 #include <pthread.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 
23 
24 static pthread_barrier_t bar;
25 
26 
27 static void *
tf(void * arg)28 tf (void *arg)
29 {
30   if (pthread_barrier_wait (&bar) != 0)
31     {
32       puts ("tf: barrier_wait failed");
33       exit (1);
34     }
35 
36   return (void *) 1l;
37 }
38 
39 
40 static int
do_test(void)41 do_test (void)
42 {
43   if (pthread_barrier_init (&bar, NULL, 3) != 0)
44     {
45       puts ("barrier_init failed");
46       exit (1);
47     }
48 
49   pthread_attr_t a;
50 
51   if (pthread_attr_init (&a) != 0)
52     {
53       puts ("attr_init failed");
54       exit (1);
55     }
56 
57   if (pthread_attr_setstacksize (&a, 1 * 1024 * 1024) != 0)
58     {
59       puts ("attr_setstacksize failed");
60       return 1;
61     }
62 
63   pthread_t th[2];
64 
65   if (pthread_create (&th[0], &a, tf, NULL) != 0)
66     {
67       puts ("1st create failed");
68       exit (1);
69     }
70 
71   if (pthread_attr_setdetachstate (&a, PTHREAD_CREATE_DETACHED) != 0)
72     {
73       puts ("attr_setdetachstate failed");
74       exit (1);
75     }
76 
77   if (pthread_create (&th[1], &a, tf, NULL) != 0)
78     {
79       puts ("1st create failed");
80       exit (1);
81     }
82 
83   if (pthread_attr_destroy (&a) != 0)
84     {
85       puts ("attr_destroy failed");
86       exit (1);
87     }
88 
89   if (pthread_detach (th[0]) != 0)
90     {
91       puts ("could not detach 1st thread");
92       exit (1);
93     }
94 
95   int err = pthread_detach (th[0]);
96   if (err == 0)
97     {
98       puts ("second detach of 1st thread succeeded");
99       exit (1);
100     }
101   if (err != EINVAL)
102     {
103       printf ("second detach of 1st thread returned %d, not EINVAL\n", err);
104       exit (1);
105     }
106 
107   err = pthread_detach (th[1]);
108   if (err == 0)
109     {
110       puts ("detach of 2nd thread succeeded");
111       exit (1);
112     }
113   if (err != EINVAL)
114     {
115       printf ("detach of 2nd thread returned %d, not EINVAL\n", err);
116       exit (1);
117     }
118 
119   exit (0);
120 }
121 
122 #define TEST_FUNCTION do_test ()
123 #include "../test-skeleton.c"
124