#include #include #include #include #include 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 (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"