a1ea733d42045c04b66f0a21d655df85b6e394da
[libc-test] / src / regression / pthread_cancel-sem_wait.c
1 // sem_wait and sem_timedwait are cancellation points
2 #include <pthread.h>
3 #include <semaphore.h>
4 #include <string.h>
5 #include "test.h"
6
7 #define TESTC(c, m) ( (c) || (t_error("%s failed (" m ")\n", #c), 0) )
8 #define TESTR(r, f, m) ( \
9         ((r) = (f)) == 0 || (t_error("%s failed: %s (" m ")\n", #f, strerror(r)), 0) )
10
11 static sem_t sem1, sem2;
12
13 static int seqno;
14
15 static void wait_cancel(void *arg)
16 {
17         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
18         while (sem_wait(&sem1));
19         pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
20         seqno = 1;
21 }
22
23 static void *start_sem_wait(void *arg)
24 {
25         wait_cancel(arg);
26         sem_wait(&sem2);
27         seqno = 2;
28         return 0;
29 }
30
31 static void *start_sem_timedwait(void *arg)
32 {
33         wait_cancel(arg);
34         sem_timedwait(&sem2, &(struct timespec){1, 0});
35         seqno = 2;
36         return 0;
37 }
38
39 int main(void)
40 {
41         pthread_t td;
42         int r;
43         void *res;
44
45         TESTR(r, sem_init(&sem1, 0, 0), "creating semaphore");
46         TESTR(r, sem_init(&sem2, 0, 1), "creating semaphore");
47
48         /* Cancellation on uncontended sem_wait */
49         seqno = 0;
50         TESTR(r, pthread_create(&td, 0, start_sem_wait, 0), "failed to create thread");
51         TESTR(r, pthread_cancel(td), "canceling");
52         sem_post(&sem1);
53         TESTR(r, pthread_join(td, &res), "joining canceled thread");
54         TESTC(res == PTHREAD_CANCELED, "canceled thread exit status");
55         TESTC(seqno == 1, "seqno");
56
57         /* Cancellation on blocking sem_wait */
58         seqno = 0;
59         sem_trywait(&sem2);
60         TESTR(r, pthread_create(&td, 0, start_sem_wait, 0), "failed to create thread");
61         TESTR(r, pthread_cancel(td), "canceling");
62         sem_post(&sem1);
63         TESTR(r, pthread_join(td, &res), "joining canceled thread");
64         TESTC(res == PTHREAD_CANCELED, "canceled thread exit status");
65         TESTC(seqno == 1, "seqno");
66
67         /* Cancellation on uncontended sem_timedwait */
68         seqno = 0;
69         sem_post(&sem2);
70         TESTR(r, pthread_create(&td, 0, start_sem_wait, 0), "failed to create thread");
71         TESTR(r, pthread_cancel(td), "canceling");
72         sem_post(&sem1);
73         TESTR(r, pthread_join(td, &res), "joining canceled thread");
74         TESTC(res == PTHREAD_CANCELED, "canceled thread exit status");
75         TESTC(seqno == 1, "seqno");
76
77         /* Cancellation on blocking sem_timedwait */
78         seqno = 0;
79         sem_trywait(&sem2);
80         TESTR(r, pthread_create(&td, 0, start_sem_wait, 0), "failed to create thread");
81         TESTR(r, pthread_cancel(td), "canceling");
82         sem_post(&sem1);
83         TESTR(r, pthread_join(td, &res), "joining canceled thread");
84         TESTC(res == PTHREAD_CANCELED, "canceled thread exit status");
85         TESTC(seqno == 1, "seqno");
86
87         return t_status;
88 }