diff options
Diffstat (limited to 'nptl/tst-cancel17.c')
-rw-r--r-- | nptl/tst-cancel17.c | 147 |
1 files changed, 133 insertions, 14 deletions
diff --git a/nptl/tst-cancel17.c b/nptl/tst-cancel17.c index 65b8c73ef8..861ca5ea69 100644 --- a/nptl/tst-cancel17.c +++ b/nptl/tst-cancel17.c @@ -18,6 +18,7 @@ 02111-1307 USA. */ #include <aio.h> +#include <errno.h> #include <pthread.h> #include <stdio.h> #include <stdlib.h> @@ -44,19 +45,44 @@ tf (void *arg) int r = pthread_barrier_wait (&b); if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) { - puts ("barrier_wait failed"); + puts ("tf: barrier_wait failed"); + exit (1); + } + + pthread_cleanup_push (cl, NULL); + + const struct aiocb *l[1] = { arg }; + + TEMP_FAILURE_RETRY (aio_suspend (l, 1, NULL)); + + pthread_cleanup_pop (0); + + puts ("tf: aio_suspend returned"); + + exit (1); +} + + +static void * +tf2 (void *arg) +{ + int r = pthread_barrier_wait (&b); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("tf2: barrier_wait failed"); exit (1); } pthread_cleanup_push (cl, NULL); const struct aiocb *l[1] = { arg }; + struct timespec ts = { .tv_sec = 1000, .tv_nsec = 0 }; - aio_suspend (l, 1, NULL); + TEMP_FAILURE_RETRY (aio_suspend (l, 1, &ts)); pthread_cleanup_pop (0); - puts ("aio_suspend returned"); + puts ("tf2: aio_suspend returned"); exit (1); } @@ -108,7 +134,7 @@ do_test (void) while (nanosleep (&ts, &ts) != 0) continue; - puts ("going to cancel in-time"); + puts ("going to cancel tf in-time"); if (pthread_cancel (th) != 0) { puts ("1st cancel failed"); @@ -129,12 +155,61 @@ do_test (void) if (cl_called == 0) { - puts ("cleanup handler not called"); + puts ("tf cleanup handler not called"); return 1; } if (cl_called > 1) { - puts ("cleanup handler called more than once"); + puts ("tf cleanup handler called more than once"); + return 1; + } + + cl_called = 0; + + if (pthread_create (&th, NULL, tf2, &a) != 0) + { + puts ("2nd create failed"); + return 1; + } + + r = pthread_barrier_wait (&b); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("2nd barrier_wait failed"); + exit (1); + } + + ts.tv_sec = 0; + ts.tv_nsec = 100000000; + while (nanosleep (&ts, &ts) != 0) + continue; + + puts ("going to cancel tf2 in-time"); + if (pthread_cancel (th) != 0) + { + puts ("2nd cancel failed"); + return 1; + } + + if (pthread_join (th, &status) != 0) + { + puts ("2nd join failed"); + return 1; + } + if (status != PTHREAD_CANCELED) + { + puts ("2nd thread not canceled"); + return 1; + } + + if (cl_called == 0) + { + puts ("tf2 cleanup handler not called"); + return 1; + } + if (cl_called > 1) + { + puts ("tf2 cleanup handler called more than once"); return 1; } @@ -156,43 +231,87 @@ do_test (void) if (pthread_create (&th, NULL, tf, &a) != 0) { - puts ("2nd create failed"); + puts ("3rd create failed"); return 1; } - puts ("going to cancel early"); + puts ("going to cancel tf early"); if (pthread_cancel (th) != 0) { - puts ("2nd cancel failed"); + puts ("3rd cancel failed"); return 1; } r = pthread_barrier_wait (&b); if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) { - puts ("barrier_wait failed"); + puts ("3rd barrier_wait failed"); exit (1); } if (pthread_join (th, &status) != 0) { - puts ("2nd join failed"); + puts ("3rd join failed"); return 1; } if (status != PTHREAD_CANCELED) { - puts ("2nd thread not canceled"); + puts ("3rd thread not canceled"); + return 1; + } + + if (cl_called == 0) + { + printf ("tf cleanup handler not called\n"); + return 1; + } + if (cl_called > 1) + { + printf ("tf cleanup handler called more than once\n"); + return 1; + } + + cl_called = 0; + + if (pthread_create (&th, NULL, tf2, &a) != 0) + { + puts ("4th create failed"); + return 1; + } + + puts ("going to cancel tf2 early"); + if (pthread_cancel (th) != 0) + { + puts ("4th cancel failed"); + return 1; + } + + r = pthread_barrier_wait (&b); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("4th barrier_wait failed"); + exit (1); + } + + if (pthread_join (th, &status) != 0) + { + puts ("4th join failed"); + return 1; + } + if (status != PTHREAD_CANCELED) + { + puts ("4th thread not canceled"); return 1; } if (cl_called == 0) { - printf ("cleanup handler not called\n"); + printf ("tf2 cleanup handler not called\n"); return 1; } if (cl_called > 1) { - printf ("cleanup handler called more than once\n"); + printf ("tf2 cleanup handler called more than once\n"); return 1; } |