2004-10-26 Jakub Jelinek <jakub@redhat.com>
[glibc/history.git] / linuxthreads / tst-cancel4.c
blob03f6bfe056dcf56be773c062b5c0a18159763319
1 /* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 /* NOTE: this tests functionality beyond POSIX. POSIX does not allow
21 exit to be called more than once. */
23 #include <errno.h>
24 #include <limits.h>
25 #include <pthread.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <sys/poll.h>
31 #include <sys/select.h>
32 #include <sys/uio.h>
33 #include <sys/wait.h>
35 /* The following interfaces are defined to be cancellation points but
36 tests are not yet implemented:
38 accept() aio_suspend() clock_nanosleep()
39 close() connect() creat()
40 fcntl() fsync() getmsg()
41 getpmsg() lockf() mq_receive()
42 mq_send() mq_timedreceive() mq_timedsend()
43 msgrcv() msgsnd() msync()
44 open() pause()
45 pread() pthread_cond_timedwait()
46 pthread_cond_wait() pthread_join() pthread_testcancel()
47 putmsg() putpmsg() pwrite()
48 recv()
49 recvfrom() recvmsg()
50 sem_timedwait() sem_wait() send()
51 sendmsg() sendto() sigpause()
52 sigsuspend() sigtimedwait() sigwait()
53 sigwaitinfo() system()
54 tcdrain()
56 Since STREAMS are not supported in the standard Linux kernel there
57 is no need to test the STREAMS related functions.
60 /* Pipe descriptors. */
61 static int fds[2];
63 /* Often used barrier for two threads. */
64 static pthread_barrier_t b2;
67 static void *
68 tf_read (void *arg)
70 int r = pthread_barrier_wait (&b2);
71 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
73 printf ("%s: barrier_wait failed\n", __FUNCTION__);
74 exit (1);
77 char buf[100];
78 ssize_t s = read (fds[0], buf, sizeof (buf));
80 printf ("%s: read returns with %zd\n", __FUNCTION__, s);
82 exit (1);
86 static void *
87 tf_readv (void *arg)
89 int r = pthread_barrier_wait (&b2);
90 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
92 printf ("%s: barrier_wait failed\n", __FUNCTION__);
93 exit (1);
96 char buf[100];
97 struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
98 ssize_t s = readv (fds[0], iov, 1);
100 printf ("%s: readv returns with %zd\n", __FUNCTION__, s);
102 exit (1);
106 static void *
107 tf_write (void *arg)
109 int r = pthread_barrier_wait (&b2);
110 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
112 printf ("%s: barrier_wait failed\n", __FUNCTION__);
113 exit (1);
116 char buf[100000];
117 memset (buf, '\0', sizeof (buf));
118 ssize_t s = write (fds[1], buf, sizeof (buf));
120 printf ("%s: write returns with %zd\n", __FUNCTION__, s);
122 exit (1);
126 static void *
127 tf_writev (void *arg)
129 int r = pthread_barrier_wait (&b2);
130 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
132 printf ("%s: barrier_wait failed\n", __FUNCTION__);
133 exit (1);
136 char buf[100000];
137 memset (buf, '\0', sizeof (buf));
138 struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
139 ssize_t s = writev (fds[1], iov, 1);
141 printf ("%s: writev returns with %zd\n", __FUNCTION__, s);
143 exit (1);
147 static void *
148 tf_sleep (void *arg)
150 int r = pthread_barrier_wait (&b2);
151 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
153 printf ("%s: barrier_wait failed\n", __FUNCTION__);
154 exit (1);
157 sleep (1000000);
159 printf ("%s: sleep returns\n", __FUNCTION__);
161 exit (1);
165 static void *
166 tf_usleep (void *arg)
168 int r = pthread_barrier_wait (&b2);
169 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
171 printf ("%s: barrier_wait failed\n", __FUNCTION__);
172 exit (1);
175 usleep ((useconds_t) ULONG_MAX);
177 printf ("%s: usleep returns\n", __FUNCTION__);
179 exit (1);
183 static void *
184 tf_nanosleep (void *arg)
186 int r = pthread_barrier_wait (&b2);
187 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
189 printf ("%s: barrier_wait failed\n", __FUNCTION__);
190 exit (1);
193 struct timespec ts = { .tv_sec = 10000000, .tv_nsec = 0 };
194 while (nanosleep (&ts, &ts) != 0)
195 continue;
197 printf ("%s: nanosleep returns\n", __FUNCTION__);
199 exit (1);
203 static void *
204 tf_select (void *arg)
206 int r = pthread_barrier_wait (&b2);
207 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
209 printf ("%s: barrier_wait failed\n", __FUNCTION__);
210 exit (1);
213 fd_set rfs;
214 FD_ZERO (&rfs);
215 FD_SET (fds[0], &rfs);
217 int s = select (fds[0] + 1, &rfs, NULL, NULL, NULL);
219 printf ("%s: select returns with %d (%s)\n", __FUNCTION__, s,
220 strerror (errno));
222 exit (1);
226 static void *
227 tf_pselect (void *arg)
229 int r = pthread_barrier_wait (&b2);
230 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
232 printf ("%s: barrier_wait failed\n", __FUNCTION__);
233 exit (1);
236 fd_set rfs;
237 FD_ZERO (&rfs);
238 FD_SET (fds[0], &rfs);
240 int s = pselect (fds[0] + 1, &rfs, NULL, NULL, NULL, NULL);
242 printf ("%s: pselect returns with %d (%s)\n", __FUNCTION__, s,
243 strerror (errno));
245 exit (1);
249 static void *
250 tf_poll (void *arg)
252 int r = pthread_barrier_wait (&b2);
253 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
255 printf ("%s: barrier_wait failed\n", __FUNCTION__);
256 exit (1);
259 struct pollfd rfs[1] = { [0] = { .fd = fds[0], .events = POLLIN } };
261 int s = poll (rfs, 1, -1);
263 printf ("%s: poll returns with %d (%s)\n", __FUNCTION__, s,
264 strerror (errno));
266 exit (1);
270 static void *
271 tf_wait (void *arg)
273 int r = pthread_barrier_wait (&b2);
274 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
276 printf ("%s: barrier_wait failed\n", __FUNCTION__);
277 exit (1);
280 pid_t pid = fork ();
281 if (pid == -1)
283 puts ("fork failed");
284 exit (1);
287 if (pid == 0)
289 /* Make the program disappear after a while. */
290 sleep (10);
291 exit (0);
294 int s = wait (NULL);
296 printf ("%s: wait returns with %d (%s)\n", __FUNCTION__, s,
297 strerror (errno));
299 exit (1);
303 static void *
304 tf_waitpid (void *arg)
306 int r = pthread_barrier_wait (&b2);
307 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
309 printf ("%s: barrier_wait failed\n", __FUNCTION__);
310 exit (1);
313 pid_t pid = fork ();
314 if (pid == -1)
316 puts ("fork failed");
317 exit (1);
320 if (pid == 0)
322 /* Make the program disappear after a while. */
323 sleep (10);
324 exit (0);
327 int s = waitpid (-1, NULL, 0);
329 printf ("%s: waitpid returns with %d (%s)\n", __FUNCTION__, s,
330 strerror (errno));
332 exit (1);
336 static void *
337 tf_waitid (void *arg)
339 int r = pthread_barrier_wait (&b2);
340 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
342 printf ("%s: barrier_wait failed\n", __FUNCTION__);
343 exit (1);
346 pid_t pid = fork ();
347 if (pid == -1)
349 puts ("fork failed");
350 exit (1);
353 if (pid == 0)
355 /* Make the program disappear after a while. */
356 sleep (10);
357 exit (0);
360 #ifndef WEXITED
361 # define WEXITED 0
362 #endif
363 siginfo_t si;
364 int s = waitid (P_PID, pid, &si, WEXITED);
366 printf ("%s: waitid returns with %d (%s)\n", __FUNCTION__, s,
367 strerror (errno));
369 exit (1);
373 static struct
375 void *(*tf) (void *);
376 int nb;
377 } tests[] =
379 { tf_read, 2 },
380 { tf_readv, 2 },
381 { tf_select, 2 },
382 { tf_pselect, 2 },
383 { tf_poll, 2 },
384 { tf_write, 2 },
385 { tf_writev, 2},
386 { tf_sleep, 2 },
387 { tf_usleep, 2 },
388 { tf_nanosleep, 2 },
389 { tf_wait, 2 },
390 { tf_waitid, 2 },
391 { tf_waitpid, 2 },
393 #define ntest_tf (sizeof (tests) / sizeof (tests[0]))
396 static int
397 do_test (void)
399 if (pipe (fds) != 0)
401 puts ("pipe failed");
402 exit (1);
405 int cnt;
406 for (cnt = 0; cnt < ntest_tf; ++cnt)
408 printf ("round %d\n", cnt);
410 if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
412 puts ("b2 init failed");
413 exit (1);
416 pthread_t th;
417 if (pthread_create (&th, NULL, tests[cnt].tf, NULL) != 0)
419 printf ("create for round %d test failed\n", cnt);
420 exit (1);
423 puts ("barrier waits");
425 int r = pthread_barrier_wait (&b2);
426 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
428 printf ("%s: barrier_wait failed\n", __FUNCTION__);
429 exit (1);
432 puts ("nanosleep delay");
434 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
435 while (nanosleep (&ts, &ts) != 0)
436 continue;
438 if (pthread_cancel (th) != 0)
440 printf ("cancel in round %d failed\n", cnt);
441 exit (1);
444 void *status;
445 if (pthread_join (th, &status) != 0)
447 printf ("join in round %d failed\n", cnt);
448 exit (1);
450 if (status != PTHREAD_CANCELED)
452 printf ("thread in round %d not canceled\n", cnt);
453 exit (1);
455 printf ("test %d successful\n", cnt);
457 if (pthread_barrier_destroy (&b2) != 0)
459 puts ("barrier_destroy failed");
460 exit (1);
464 return 0;
467 #define TIMEOUT 60
468 #define TEST_FUNCTION do_test ()
469 #include "../test-skeleton.c"