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)24 tf (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()48 do_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