diff options
Diffstat (limited to 'nptl')
-rw-r--r-- | nptl/ChangeLog | 2 | ||||
-rw-r--r-- | nptl/Makefile | 4 | ||||
-rw-r--r-- | nptl/tst-cancel24.cc | 113 |
3 files changed, 118 insertions, 1 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 761308de65..c7c2acb8d9 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -3,6 +3,8 @@ [BZ #1913] * sysdeps/unix/sysv/linux/i386/i486/sem_wait.S (__new_sem_wait): Fix unwind info. Remove useless branch prediction prefix. + * tst-cancel24.cc: New file. + * Makefile: Add rules to build and run tst-cancel24. 2005-12-21 Roland McGrath <roland@redhat.com> diff --git a/nptl/Makefile b/nptl/Makefile index 7602c50c4d..c061b9d646 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -220,7 +220,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 \ tst-cancel6 tst-cancel7 tst-cancel8 tst-cancel9 tst-cancel10 \ tst-cancel11 tst-cancel12 tst-cancel13 tst-cancel14 tst-cancel15 \ tst-cancel16 tst-cancel17 tst-cancel18 tst-cancel19 tst-cancel20 \ - tst-cancel21 tst-cancel22 tst-cancel23 \ + tst-cancel21 tst-cancel22 tst-cancel23 tst-cancel24 \ tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 tst-cleanup4 \ tst-flock1 tst-flock2 \ tst-signal1 tst-signal2 tst-signal3 tst-signal4 tst-signal5 \ @@ -479,6 +479,8 @@ $(objpfx)tst-clock2: $(common-objpfx)rt/librt.a $(objpfx)tst-rwlock14: $(common-objpfx)rt/librt.a endif +LDFLAGS-tst-cancel24 = -lstdc++ + extra-B-pthread.so = -B$(common-objpfx)nptl/ $(objpfx)libpthread.so: $(addprefix $(objpfx),$(crti-objs) $(crtn-objs)) $(objpfx)libpthread.so: +preinit += $(addprefix $(objpfx),$(crti-objs)) diff --git a/nptl/tst-cancel24.cc b/nptl/tst-cancel24.cc new file mode 100644 index 0000000000..52cf079d5a --- /dev/null +++ b/nptl/tst-cancel24.cc @@ -0,0 +1,113 @@ +#include <cstdlib> +#include <cstdio> +#include <pthread.h> +#include <semaphore.h> +#include <unistd.h> + + +static volatile bool destr_called; +static volatile bool except_caught; + +static pthread_barrier_t b; + + +struct monitor +{ + // gcc is broken and would generate a warning without this dummy + // constructor. + monitor () { } + ~monitor() { destr_called = true; } +}; + + +static void * +tf (void *arg) +{ + sem_t *s = static_cast<sem_t *> (arg); + + try + { + monitor m; + + pthread_barrier_wait (&b); + + while (1) + sem_wait (s); + } + catch (...) + { + except_caught = true; + throw; + } + + return NULL; +} + + +static int +do_test () +{ + if (pthread_barrier_init (&b, NULL, 2) != 0) + { + puts ("barrier_init failed"); + return 1; + } + + sem_t s; + if (sem_init (&s, 0, 0) != 0) + { + puts ("sem_init failed"); + return 1; + } + + pthread_t th; + if (pthread_create (&th, NULL, tf, &s) != 0) + { + puts ("pthread_create failed"); + return 1; + } + + pthread_barrier_wait (&b); + + /* There is unfortunately no better method to try to assure the + child thread reached the sem_wait call and is actually waiting + than to sleep here. */ + sleep (1); + + if (pthread_cancel (th) != 0) + { + puts ("cancel failed"); + return 1; + } + + void *res; + if (pthread_join (th, &res) != 0) + { + puts ("join failed"); + return 1; + } + + if (res != PTHREAD_CANCELED) + { + puts ("thread was not canceled"); + return 1; + } + + if (! except_caught) + { + puts ("exception not caught"); + return 1; + } + + if (! destr_called) + { + puts ("destructor not called"); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#define TIMEOUT 3 +#include "../test-skeleton.c" |