Fix inconsistent passwd compensation in nss/bug17079.c
[glibc.git] / nptl / tst-cond25.c
blobbe0bec484d780c6544d46b5df5078787e9cc69f9
1 /* Verify that condition variables synchronized by PI mutexes don't hang on
2 on cancellation.
3 Copyright (C) 2012-2015 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
20 #include <pthread.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdint.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <sys/types.h>
27 #include <sys/syscall.h>
28 #include <unistd.h>
29 #include <sys/time.h>
30 #include <time.h>
32 #define NUM 5
33 #define ITERS 10000
34 #define COUNT 100
36 typedef void *(*thr_func) (void *);
38 pthread_mutex_t mutex;
39 pthread_cond_t cond;
41 void cleanup (void *u)
43 /* pthread_cond_wait should always return with the mutex locked. The
44 pthread_mutex_unlock implementation does not actually check whether we
45 own the mutex for several mutex kinds, so check this explicitly. */
46 int ret = pthread_mutex_trylock (&mutex);
47 if (ret != EDEADLK && ret != EBUSY)
49 printf ("mutex not locked in cleanup %d\n", ret);
50 abort ();
52 if (pthread_mutex_unlock (&mutex))
53 abort ();
56 void *
57 signaller (void *u)
59 int i, ret = 0;
60 void *tret = NULL;
62 for (i = 0; i < ITERS; i++)
64 if ((ret = pthread_mutex_lock (&mutex)) != 0)
66 tret = (void *)1;
67 printf ("signaller:mutex_lock failed: %s\n", strerror (ret));
68 goto out;
70 if ((ret = pthread_cond_signal (&cond)) != 0)
72 tret = (void *)1;
73 printf ("signaller:signal failed: %s\n", strerror (ret));
74 goto unlock_out;
76 if ((ret = pthread_mutex_unlock (&mutex)) != 0)
78 tret = (void *)1;
79 printf ("signaller:mutex_unlock failed: %s\n", strerror (ret));
80 goto out;
82 pthread_testcancel ();
85 out:
86 return tret;
88 unlock_out:
89 if ((ret = pthread_mutex_unlock (&mutex)) != 0)
90 printf ("signaller:mutex_unlock[2] failed: %s\n", strerror (ret));
91 goto out;
94 void *
95 waiter (void *u)
97 int i, ret = 0;
98 void *tret = NULL;
99 int seq = (uintptr_t) u;
101 for (i = 0; i < ITERS / NUM; i++)
103 if ((ret = pthread_mutex_lock (&mutex)) != 0)
105 tret = (void *) (uintptr_t) 1;
106 printf ("waiter[%u]:mutex_lock failed: %s\n", seq, strerror (ret));
107 goto out;
109 pthread_cleanup_push (cleanup, NULL);
111 if ((ret = pthread_cond_wait (&cond, &mutex)) != 0)
113 tret = (void *) (uintptr_t) 1;
114 printf ("waiter[%u]:wait failed: %s\n", seq, strerror (ret));
115 goto unlock_out;
118 if ((ret = pthread_mutex_unlock (&mutex)) != 0)
120 tret = (void *) (uintptr_t) 1;
121 printf ("waiter[%u]:mutex_unlock failed: %s\n", seq, strerror (ret));
122 goto out;
124 pthread_cleanup_pop (0);
127 out:
128 puts ("waiter tests done");
129 return tret;
131 unlock_out:
132 if ((ret = pthread_mutex_unlock (&mutex)) != 0)
133 printf ("waiter:mutex_unlock[2] failed: %s\n", strerror (ret));
134 goto out;
137 void *
138 timed_waiter (void *u)
140 int i, ret;
141 void *tret = NULL;
142 int seq = (uintptr_t) u;
144 for (i = 0; i < ITERS / NUM; i++)
146 struct timespec ts;
148 if ((ret = clock_gettime(CLOCK_REALTIME, &ts)) != 0)
150 tret = (void *) (uintptr_t) 1;
151 printf ("%u:clock_gettime failed: %s\n", seq, strerror (errno));
152 goto out;
154 ts.tv_sec += 20;
156 if ((ret = pthread_mutex_lock (&mutex)) != 0)
158 tret = (void *) (uintptr_t) 1;
159 printf ("waiter[%u]:mutex_lock failed: %s\n", seq, strerror (ret));
160 goto out;
162 pthread_cleanup_push (cleanup, NULL);
164 /* We should not time out either. */
165 if ((ret = pthread_cond_timedwait (&cond, &mutex, &ts)) != 0)
167 tret = (void *) (uintptr_t) 1;
168 printf ("waiter[%u]:timedwait failed: %s\n", seq, strerror (ret));
169 goto unlock_out;
171 if ((ret = pthread_mutex_unlock (&mutex)) != 0)
173 tret = (void *) (uintptr_t) 1;
174 printf ("waiter[%u]:mutex_unlock failed: %s\n", seq, strerror (ret));
175 goto out;
177 pthread_cleanup_pop (0);
180 out:
181 puts ("timed_waiter tests done");
182 return tret;
184 unlock_out:
185 if ((ret = pthread_mutex_unlock (&mutex)) != 0)
186 printf ("waiter[%u]:mutex_unlock[2] failed: %s\n", seq, strerror (ret));
187 goto out;
191 do_test_wait (thr_func f)
193 pthread_t w[NUM];
194 pthread_t s;
195 pthread_mutexattr_t attr;
196 int i, j, ret = 0;
197 void *thr_ret;
199 for (i = 0; i < COUNT; i++)
201 if ((ret = pthread_mutexattr_init (&attr)) != 0)
203 printf ("mutexattr_init failed: %s\n", strerror (ret));
204 goto out;
207 if ((ret = pthread_mutexattr_setprotocol (&attr,
208 PTHREAD_PRIO_INHERIT)) != 0)
210 printf ("mutexattr_setprotocol failed: %s\n", strerror (ret));
211 goto out;
214 if ((ret = pthread_cond_init (&cond, NULL)) != 0)
216 printf ("cond_init failed: %s\n", strerror (ret));
217 goto out;
220 if ((ret = pthread_mutex_init (&mutex, &attr)) != 0)
222 printf ("mutex_init failed: %s\n", strerror (ret));
223 goto out;
226 for (j = 0; j < NUM; j++)
227 if ((ret = pthread_create (&w[j], NULL,
228 f, (void *) (uintptr_t) j)) != 0)
230 printf ("waiter[%d]: create failed: %s\n", j, strerror (ret));
231 goto out;
234 if ((ret = pthread_create (&s, NULL, signaller, NULL)) != 0)
236 printf ("signaller: create failed: %s\n", strerror (ret));
237 goto out;
240 for (j = 0; j < NUM; j++)
242 pthread_cancel (w[j]);
244 if ((ret = pthread_join (w[j], &thr_ret)) != 0)
246 printf ("waiter[%d]: join failed: %s\n", j, strerror (ret));
247 goto out;
250 if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED)
252 ret = 1;
253 goto out;
257 /* The signalling thread could have ended before it was cancelled. */
258 pthread_cancel (s);
260 if ((ret = pthread_join (s, &thr_ret)) != 0)
262 printf ("signaller: join failed: %s\n", strerror (ret));
263 goto out;
266 if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED)
268 ret = 1;
269 goto out;
273 out:
274 return ret;
278 do_test (int argc, char **argv)
280 int ret = do_test_wait (waiter);
282 if (ret)
283 return ret;
285 return do_test_wait (timed_waiter);
288 #define TIMEOUT 5
289 #include "../test-skeleton.c"