blob: 11d78822722966389491cabbe9133200680f1a47 [file] [log] [blame]
Brian Waters13d96012017-12-08 16:53:31 -06001#include <pthread.h>
2#include <stdio.h>
3#include <strings.h>
4#include <assert.h>
5
6static pthread_barrier_t bar;
7static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
8static pthread_cond_t cnd = PTHREAD_COND_INITIALIZER;
9static int called = 0;
10
11#ifndef ASSERT
12#define ASSERT(x) assert(x)
13#endif /* ASSERT */
14
15static void cleanupmutex(void * arg)
16{
17 printf("cancelation cleanup handler called\n");
18 if (arg) {
19 ASSERT( pthread_mutex_unlock((pthread_mutex_t *)arg) == 0 );
20 called++;
21 }
22
23}
24
25static void * mythread(void * a)
26{
27 int ret;
28
29 /* lock mutex */
30 ASSERT( pthread_mutex_lock(&mtx) == 0 );
31
32 /* Push cleanup */
33 pthread_cleanup_push(cleanupmutex, &mtx);
34
35 printf("thread synchronization (mutex acquired)\n");
36
37 /* Wake the other thread */
38 ret = pthread_barrier_wait(&bar);
39 ASSERT( (ret == 0) || (ret == PTHREAD_BARRIER_SERIAL_THREAD) );
40
41 /* Now wait for the condition, this unlocks the mutex */
42 do {
43 printf("thread waiting cond\n");
44 ASSERT( pthread_cond_wait(&cnd, &mtx) == 0);
45 printf("thread woken\n");
46 } while (1);
47
48 /* Cleanup, never reached */
49 pthread_cleanup_pop(1);
50 return NULL;
51}
52
53int main(int argc, char * argv[])
54{
55 int ret;
56 pthread_t thr;
57 void * dummy;
58
59 /* initialize the barrier */
60 ASSERT( pthread_barrier_init(&bar, NULL, 2) == 0 );
61
62 printf("Creating thread\n");
63
64 /* Create the thread */
65 ASSERT( pthread_create(&thr, NULL, mythread, NULL) == 0 );
66
67 printf("main synchronization\n");
68 ret = pthread_barrier_wait(&bar);
69 ASSERT( (ret == 0) || (ret == PTHREAD_BARRIER_SERIAL_THREAD) );
70
71 ASSERT( pthread_mutex_lock(&mtx) == 0 );
72 printf("main: thread is now waiting for condvar\n");
73
74 /* Cancel the thread */
75 ASSERT( pthread_cancel(thr) == 0 );
76
77 /* Now, unlock, so that the thread can actually really exit */
78 ASSERT( pthread_mutex_unlock(&mtx) == 0 );
79
80 /* Release thread resources */
81 ASSERT( pthread_join(thr, &dummy) == 0 );
82
83 if (called == 1)
84 printf("Test successful!\n");
85 else
86 printf("Test failed! Cleanup was not called (& lock not released)\n");
87
88 return 0;
89
90}