1#include <pthread.h>
2#include <semaphore.h>
3#include <stdlib.h>
4#include <stdio.h>
5#include <unistd.h>
6
7
8static volatile bool destr_called;
9static volatile bool except_caught;
10
11static pthread_barrier_t b;
12
13
14struct 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
23static void *
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 (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
47static int
48do_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

source code of glibc/nptl/tst-cancel24.cc