Test of cancellation after cond_signal.
[kopensolaris-gnu/glibc.git] / nptl / tst-cond22.c
1 #include <pthreadP.h>
2 #include <stdio.h>
3
4
5 static pthread_barrier_t b;
6 static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
7 static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
8
9
10 static void
11 cl (void *arg)
12 {
13   pthread_mutex_unlock (&m);
14 }
15
16
17 static void *
18 tf (void *arg)
19 {
20   if (pthread_mutex_lock (&m) != 0)
21     {
22       printf ("%s: mutex_lock failed\n", __func__);
23       exit (1);
24     }
25   int e = pthread_barrier_wait (&b);
26   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
27     {
28       printf ("%s: barrier_wait failed\n", __func__);
29       exit (1);
30     }
31   pthread_cleanup_push (cl, NULL);
32   if (pthread_cond_wait (&c, &m) != 0)
33     {
34       printf ("%s: cond_wait failed\n", __func__);
35       exit (1);
36     }
37   pthread_cleanup_pop (0);
38   if (pthread_mutex_unlock (&m) != 0)
39     {
40       printf ("%s: mutex_unlock failed\n", __func__);
41       exit (1);
42     }
43   return NULL;
44 }
45
46
47 static int
48 do_test (void)
49 {
50   int status = 0;
51
52   if (pthread_barrier_init (&b, NULL, 2) != 0)
53     {
54       puts ("barrier_init failed");
55       return 1;
56     }
57
58   pthread_t th;
59   if (pthread_create (&th, NULL, tf, NULL) != 0)
60     {
61       puts ("1st create failed");
62       return 1;
63     }
64   int e = pthread_barrier_wait (&b);
65   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
66     {
67       puts ("1st barrier_wait failed");
68       return 1;
69     }
70   if (pthread_mutex_lock (&m) != 0)
71     {
72       puts ("1st mutex_lock failed");
73       return 1;
74     }
75   if (pthread_cond_signal (&c) != 0)
76     {
77       puts ("1st cond_signal failed");
78       return 1;
79     }
80   if (pthread_cancel (th) != 0)
81     {
82       puts ("cancel failed");
83       return 1;
84     }
85   if (pthread_mutex_unlock (&m) != 0)
86     {
87       puts ("1st mutex_unlock failed");
88       return 1;
89     }
90   void *res;
91   if (pthread_join (th, &res) != 0)
92     {
93       puts ("1st join failed");
94       return 1;
95     }
96   if (res != PTHREAD_CANCELED)
97     {
98       puts ("first thread not canceled");
99       status = 1;
100     }
101
102   printf ("cond = { %d, %x, %lld, %lld, %lld, %p, %u, %u }\n",
103           c.__data.__lock, c.__data.__futex, c.__data.__total_seq,
104           c.__data.__wakeup_seq, c.__data.__woken_seq, c.__data.__mutex,
105           c.__data.__nwaiters, c.__data.__broadcast_seq);
106
107   if (pthread_create (&th, NULL, tf, NULL) != 0)
108     {
109       puts ("2nd create failed");
110       return 1;
111     }
112   e = pthread_barrier_wait (&b);
113   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
114     {
115       puts ("2nd barrier_wait failed");
116       return 1;
117     }
118   if (pthread_mutex_lock (&m) != 0)
119     {
120       puts ("2nd mutex_lock failed");
121       return 1;
122     }
123   if (pthread_cond_signal (&c) != 0)
124     {
125       puts ("2nd cond_signal failed");
126       return 1;
127     }
128   if (pthread_mutex_unlock (&m) != 0)
129     {
130       puts ("2nd mutex_unlock failed");
131       return 1;
132     }
133   if (pthread_join (th, &res) != 0)
134     {
135       puts ("2nd join failed");
136       return 1;
137     }
138   if (res != NULL)
139     {
140       puts ("2nd thread canceled");
141       status = 1;
142     }
143
144   printf ("cond = { %d, %x, %lld, %lld, %lld, %p, %u, %u }\n",
145           c.__data.__lock, c.__data.__futex, c.__data.__total_seq,
146           c.__data.__wakeup_seq, c.__data.__woken_seq, c.__data.__mutex,
147           c.__data.__nwaiters, c.__data.__broadcast_seq);
148
149   return status;
150 }
151
152 #define TEST_FUNCTION do_test ()
153 #include "../test-skeleton.c"