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. |
18 | monitor () { } |
19 | ~monitor() { destr_called = true; } |
20 | }; |
21 | |
22 | |
23 | static void * |
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 (barrier: &b); |
33 | |
34 | while (1) |
35 | sem_wait (sem: s); |
36 | } |
37 | catch (...) |
38 | { |
39 | except_caught = true; |
40 | throw; |
41 | } |
42 | |
43 | return NULL; |
44 | } |
45 | |
46 | |
47 | static int |
48 | do_test () |
49 | { |
50 | if (pthread_barrier_init (barrier: &b, NULL, count: 2) != 0) |
51 | { |
52 | puts (s: "barrier_init failed" ); |
53 | return 1; |
54 | } |
55 | |
56 | sem_t s; |
57 | if (sem_init (sem: &s, pshared: 0, value: 0) != 0) |
58 | { |
59 | puts (s: "sem_init failed" ); |
60 | return 1; |
61 | } |
62 | |
63 | pthread_t th; |
64 | if (pthread_create (newthread: &th, NULL, start_routine: tf, arg: &s) != 0) |
65 | { |
66 | puts (s: "pthread_create failed" ); |
67 | return 1; |
68 | } |
69 | |
70 | pthread_barrier_wait (barrier: &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 (seconds: 1); |
76 | |
77 | if (pthread_cancel (th: th) != 0) |
78 | { |
79 | puts (s: "cancel failed" ); |
80 | return 1; |
81 | } |
82 | |
83 | void *res; |
84 | if (pthread_join (th: th, thread_return: &res) != 0) |
85 | { |
86 | puts (s: "join failed" ); |
87 | return 1; |
88 | } |
89 | |
90 | if (res != PTHREAD_CANCELED) |
91 | { |
92 | puts (s: "thread was not canceled" ); |
93 | return 1; |
94 | } |
95 | |
96 | if (! except_caught) |
97 | { |
98 | puts (s: "exception not caught" ); |
99 | return 1; |
100 | } |
101 | |
102 | if (! destr_called) |
103 | { |
104 | puts (s: "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 | |