1 #include <pthread.h> 2 #include <semaphore.h> 3 #include <stdlib.h> 4 #include <stdio.h> 5 #include <unistd.h> 6 7 8 static volatile bool destr_called; 9 static volatile bool except_caught; 10 11 static pthread_barrier_t b; 12 13 14 struct monitor 15 { 16 // gcc is broken and would generate a warning without this dummy 17 // constructor. monitormonitor18 monitor () { } ~monitormonitor19 ~monitor() { destr_called = true; } 20 }; 21 22 23 static void * tf(void * arg)24tf (void *arg) 25 { 26 sem_t *s = static_cast<sem_t *> (arg); 27 28 try 29 { 30 monitor m; 31 32 pthread_barrier_wait (&b); 33 34 while (1) 35 sem_wait (s); 36 } 37 catch (...) 38 { 39 except_caught = true; 40 throw; 41 } 42 43 return NULL; 44 } 45 46 47 static int do_test()48do_test () 49 { 50 if (pthread_barrier_init (&b, NULL, 2) != 0) 51 { 52 puts ("barrier_init failed"); 53 return 1; 54 } 55 56 sem_t s; 57 if (sem_init (&s, 0, 0) != 0) 58 { 59 puts ("sem_init failed"); 60 return 1; 61 } 62 63 pthread_t th; 64 if (pthread_create (&th, NULL, tf, &s) != 0) 65 { 66 puts ("pthread_create failed"); 67 return 1; 68 } 69 70 pthread_barrier_wait (&b); 71 72 /* There is unfortunately no better method to try to assure the 73 child thread reached the sem_wait call and is actually waiting 74 than to sleep here. */ 75 sleep (1); 76 77 if (pthread_cancel (th) != 0) 78 { 79 puts ("cancel failed"); 80 return 1; 81 } 82 83 void *res; 84 if (pthread_join (th, &res) != 0) 85 { 86 puts ("join failed"); 87 return 1; 88 } 89 90 if (res != PTHREAD_CANCELED) 91 { 92 puts ("thread was not canceled"); 93 return 1; 94 } 95 96 if (! except_caught) 97 { 98 puts ("exception not caught"); 99 return 1; 100 } 101 102 if (! destr_called) 103 { 104 puts ("destructor not called"); 105 return 1; 106 } 107 108 return 0; 109 } 110 111 #define TEST_FUNCTION do_test () 112 #define TIMEOUT 3 113 #include "../test-skeleton.c" 114