diff options
Diffstat (limited to 'sysdeps/pthread')
-rw-r--r-- | sysdeps/pthread/Makefile | 8 | ||||
-rw-r--r-- | sysdeps/pthread/tst-cancel-self-cancelstate.c | 65 | ||||
-rw-r--r-- | sysdeps/pthread/tst-cancel-self.c | 48 | ||||
-rw-r--r-- | sysdeps/pthread/tst-cancel9.c | 125 | ||||
-rw-r--r-- | sysdeps/pthread/tst-cancelx9.c | 1 |
5 files changed, 244 insertions, 3 deletions
diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile index a8e83d9d16..c9ba6f8f12 100644 --- a/sysdeps/pthread/Makefile +++ b/sysdeps/pthread/Makefile @@ -51,9 +51,10 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ tst-barrier1 tst-barrier2 tst-barrier3 tst-barrier4 \ tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \ tst-basic7 \ + tst-cancel-self tst-cancel-self-cancelstate \ tst-cancel-self-canceltype tst-cancel-self-testcancel \ tst-cancel1 tst-cancel2 tst-cancel3 \ - tst-cancel6 tst-cancel8 tst-cancel10 tst-cancel11 \ + tst-cancel6 tst-cancel8 tst-cancel9 tst-cancel10 tst-cancel11 \ tst-cancel12 tst-cancel14 tst-cancel15 tst-cancel18 tst-cancel19 \ tst-cancel21 \ tst-cancel22 tst-cancel23 tst-cancel26 tst-cancel27 tst-cancel28 \ @@ -115,8 +116,8 @@ tests-nolibpthread = tst-unload CFLAGS-tst-cleanup2.c += -fno-builtin CFLAGS-tst-cleanupx2.c += -fno-builtin -tests += tst-cancelx2 tst-cancelx3 tst-cancelx6 tst-cancelx8 tst-cancelx10 \ - tst-cancelx11 tst-cancelx12 tst-cancelx14 tst-cancelx15 \ +tests += tst-cancelx2 tst-cancelx3 tst-cancelx6 tst-cancelx8 tst-cancelx9 \ + tst-cancelx10 tst-cancelx11 tst-cancelx12 tst-cancelx14 tst-cancelx15 \ tst-cancelx18 tst-cancelx21 \ tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 @@ -155,6 +156,7 @@ CFLAGS-tst-cancelx2.c += -fexceptions CFLAGS-tst-cancelx3.c += -fexceptions CFLAGS-tst-cancelx6.c += -fexceptions CFLAGS-tst-cancelx8.c += -fexceptions +CFLAGS-tst-cancelx9.c += -fexceptions CFLAGS-tst-cancelx10.c += -fexceptions CFLAGS-tst-cancelx11.c += -fexceptions CFLAGS-tst-cancelx12.c += -fexceptions diff --git a/sysdeps/pthread/tst-cancel-self-cancelstate.c b/sysdeps/pthread/tst-cancel-self-cancelstate.c new file mode 100644 index 0000000000..d1d2b50cf0 --- /dev/null +++ b/sysdeps/pthread/tst-cancel-self-cancelstate.c @@ -0,0 +1,65 @@ +/* Copyright (C) 2012-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include "tst-cancel-self-cleanup.c" + + +static int +do_test (void) +{ + int ret = 0; + volatile int should_fail = 1; + + pthread_cleanup_push (cleanup, (void *) &should_fail); + + if ((ret = pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL)) != 0) + { + printf ("setcancelstate(disable) failed: %s\n", strerror (ret)); + exit (1); + } + + if ((ret = pthread_cancel (pthread_self ())) != 0) + { + printf ("cancel failed: %s\n", strerror (ret)); + exit (1); + } + + usleep (100); + should_fail = 0; + + if ((ret = pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL)) != 0) + { + printf ("setcancelstate(enable) failed: %s\n", strerror (ret)); + exit (1); + } + + /* The write syscall within this printf should give us our cancellation + point. */ + printf ("Could not cancel self.\n"); + pthread_cleanup_pop (0); + + return 1; +} + + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cancel-self.c b/sysdeps/pthread/tst-cancel-self.c new file mode 100644 index 0000000000..9d7316d5ca --- /dev/null +++ b/sysdeps/pthread/tst-cancel-self.c @@ -0,0 +1,48 @@ +/* Copyright (C) 2012-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include "tst-cancel-self-cleanup.c" + + +static int +do_test (void) +{ + int ret = 0, should_fail = 0; + + pthread_cleanup_push (cleanup, &should_fail); + if ((ret = pthread_cancel (pthread_self ())) != 0) + { + printf ("cancel failed: %s\n", strerror (ret)); + exit (1); + } + + /* The write syscall within this printf should give us our cancellation + point. */ + printf ("Could not cancel self.\n"); + pthread_cleanup_pop (0); + + return 1; +} + + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cancel9.c b/sysdeps/pthread/tst-cancel9.c new file mode 100644 index 0000000000..02d7c3a091 --- /dev/null +++ b/sysdeps/pthread/tst-cancel9.c @@ -0,0 +1,125 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <fcntl.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + + +static pthread_barrier_t b; + + +static void +cleanup (void *arg) +{ + fputs ("in cleanup\n", stdout); +} + + +static void * +tf (void *arg) +{ + int fd = open ("/dev/null", O_RDWR); + if (fd == -1) + { + puts ("cannot open /dev/null"); + exit (1); + } + FILE *fp = fdopen (fd, "w"); + if (fp == NULL) + { + puts ("fdopen failed"); + exit (1); + } + + pthread_cleanup_push (cleanup, NULL); + + int e = pthread_barrier_wait (&b); + if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("barrier_wait failed"); + exit (1); + } + + while (1) + /* fprintf() uses write() which is a cancallation point. */ + fprintf (fp, "foo"); + + pthread_cleanup_pop (0); + + return NULL; +} + + +static int +do_test (void) +{ + if (pthread_barrier_init (&b, NULL, 2) != 0) + { + puts ("barrier_init failed"); + exit (1); + } + + pthread_t th; + if (pthread_create (&th, NULL, tf, NULL) != 0) + { + puts ("create failed"); + return 1; + } + + int e = pthread_barrier_wait (&b); + if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("barrier_wait failed"); + exit (1); + } + + sleep (1); + + puts ("cancel now"); + + if (pthread_cancel (th) != 0) + { + puts ("cancel failed"); + exit (1); + } + + puts ("waiting for the child"); + + void *r; + if (pthread_join (th, &r) != 0) + { + puts ("join failed"); + exit (1); + } + + if (r != PTHREAD_CANCELED) + { + puts ("thread wasn't canceled"); + exit (1); + } + + return 0; +} + + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cancelx9.c b/sysdeps/pthread/tst-cancelx9.c new file mode 100644 index 0000000000..9d84663d77 --- /dev/null +++ b/sysdeps/pthread/tst-cancelx9.c @@ -0,0 +1 @@ +#include "tst-cancel9.c" |