1 /* Copyright (C) 2002-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 <pthread.h>
19 #include <signal.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 
25 static pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER;
26 static pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER;
27 
28 static int cntr;
29 
30 
31 static void
cleanup(void * arg)32 cleanup (void *arg)
33 {
34   if (arg != (void *) 42l)
35     cntr = 42;
36   else
37     cntr = 1;
38 }
39 
40 
41 static void *
tf(void * arg)42 tf (void *arg)
43 {
44   /* Ignore all signals.  This must not have any effect on delivering
45      the cancellation signal.  */
46   sigset_t ss;
47 
48   sigfillset (&ss);
49 
50   if (pthread_sigmask (SIG_BLOCK, &ss, NULL) != 0)
51     {
52       puts ("pthread_sigmask failed");
53       exit (1);
54     }
55 
56   pthread_cleanup_push (cleanup, (void *) 42l);
57 
58   int err = pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
59   if (err != 0)
60     {
61       printf ("setcanceltype failed: %s\n", strerror (err));
62       exit (1);
63     }
64   /* The following code is not standard compliant: the mutex functions
65      must not be called with asynchronous cancellation enabled.  */
66 
67   err = pthread_mutex_unlock (&m2);
68   if (err != 0)
69     {
70       printf ("child: mutex_unlock failed: %s\n", strerror (err));
71       exit (1);
72     }
73 
74   err = pthread_mutex_lock (&m1);
75   if (err != 0)
76     {
77       printf ("child: 1st mutex_lock failed: %s\n", strerror (err));
78       exit (1);
79     }
80 
81   /* We should never come here.  */
82 
83   pthread_cleanup_pop (0);
84 
85   return NULL;
86 }
87 
88 
89 static int
do_test(void)90 do_test (void)
91 {
92   int err;
93   pthread_t th;
94   int result = 0;
95   void *retval;
96 
97   /* Get the mutexes.  */
98   err = pthread_mutex_lock (&m1);
99   if (err != 0)
100     {
101       printf ("parent: 1st mutex_lock failed: %s\n", strerror (err));
102       return 1;
103     }
104   err = pthread_mutex_lock (&m2);
105   if (err != 0)
106     {
107       printf ("parent: 2nd mutex_lock failed: %s\n", strerror (err));
108       return 1;
109     }
110 
111   err = pthread_create (&th, NULL, tf, NULL);
112   if (err != 0)
113     {
114       printf ("create failed: %s\n", strerror (err));
115       return 1;
116     }
117 
118   err = pthread_mutex_lock (&m2);
119   if (err != 0)
120     {
121       printf ("parent: 3rd mutex_lock failed: %s\n", strerror (err));
122       return 1;
123     }
124 
125   err = pthread_cancel (th);
126   if (err != 0)
127     {
128       printf ("cancel failed: %s\n", strerror (err));
129       return 1;
130     }
131 
132   err = pthread_join (th, &retval);
133   if (err != 0)
134     {
135       printf ("join failed: %s\n", strerror (err));
136       return 1;
137     }
138 
139   if (retval != PTHREAD_CANCELED)
140     {
141       printf ("wrong return value: %p\n", retval);
142       result = 1;
143     }
144 
145   if (cntr == 42)
146     {
147       puts ("cleanup handler called with wrong argument");
148       result = 1;
149     }
150   else if (cntr != 1)
151     {
152       puts ("cleanup handling not called");
153       result = 1;
154     }
155 
156   return result;
157 }
158 
159 
160 #define TEST_FUNCTION do_test ()
161 #include "../test-skeleton.c"
162