1032424fd85d7b21ecefc9aa3aed21c8299c89487bart/** Cancel a thread that holds a lock on a mutex. */
2032424fd85d7b21ecefc9aa3aed21c8299c89487bart
3032424fd85d7b21ecefc9aa3aed21c8299c89487bart
4032424fd85d7b21ecefc9aa3aed21c8299c89487bart#include <assert.h>
5032424fd85d7b21ecefc9aa3aed21c8299c89487bart#include <pthread.h>
6032424fd85d7b21ecefc9aa3aed21c8299c89487bart#include <stdio.h>
7032424fd85d7b21ecefc9aa3aed21c8299c89487bart
8032424fd85d7b21ecefc9aa3aed21c8299c89487bart
9032424fd85d7b21ecefc9aa3aed21c8299c89487bartpthread_cond_t  s_cond;
10032424fd85d7b21ecefc9aa3aed21c8299c89487bartpthread_mutex_t s_mutex1;
11032424fd85d7b21ecefc9aa3aed21c8299c89487bartpthread_mutex_t s_mutex2;
12032424fd85d7b21ecefc9aa3aed21c8299c89487bart
13032424fd85d7b21ecefc9aa3aed21c8299c89487bart
14032424fd85d7b21ecefc9aa3aed21c8299c89487bartstatic void* thread(void* arg)
15032424fd85d7b21ecefc9aa3aed21c8299c89487bart{
16032424fd85d7b21ecefc9aa3aed21c8299c89487bart  /* Lock s_mutex2. */
17032424fd85d7b21ecefc9aa3aed21c8299c89487bart  pthread_mutex_lock(&s_mutex2);
18032424fd85d7b21ecefc9aa3aed21c8299c89487bart  /* Inform the main thread that s_mutex2 has been locked, and wait for pthread_cancel(). */
19032424fd85d7b21ecefc9aa3aed21c8299c89487bart  pthread_mutex_lock(&s_mutex1);
20032424fd85d7b21ecefc9aa3aed21c8299c89487bart  pthread_cond_signal(&s_cond);
21032424fd85d7b21ecefc9aa3aed21c8299c89487bart  pthread_cond_wait(&s_cond, &s_mutex1);
22032424fd85d7b21ecefc9aa3aed21c8299c89487bart  return 0;
23032424fd85d7b21ecefc9aa3aed21c8299c89487bart}
24032424fd85d7b21ecefc9aa3aed21c8299c89487bart
25032424fd85d7b21ecefc9aa3aed21c8299c89487bartint main(int argc, char** argv)
26032424fd85d7b21ecefc9aa3aed21c8299c89487bart{
27032424fd85d7b21ecefc9aa3aed21c8299c89487bart  pthread_t tid;
28032424fd85d7b21ecefc9aa3aed21c8299c89487bart
29032424fd85d7b21ecefc9aa3aed21c8299c89487bart  /* Initialize synchronization objects. */
30032424fd85d7b21ecefc9aa3aed21c8299c89487bart  pthread_cond_init(&s_cond, 0);
31032424fd85d7b21ecefc9aa3aed21c8299c89487bart  pthread_mutex_init(&s_mutex1, 0);
32032424fd85d7b21ecefc9aa3aed21c8299c89487bart  pthread_mutex_init(&s_mutex2, 0);
33032424fd85d7b21ecefc9aa3aed21c8299c89487bart
34032424fd85d7b21ecefc9aa3aed21c8299c89487bart  /* Create thread. */
35032424fd85d7b21ecefc9aa3aed21c8299c89487bart  pthread_mutex_lock(&s_mutex1);
36032424fd85d7b21ecefc9aa3aed21c8299c89487bart  pthread_create(&tid, 0, &thread, 0);
37032424fd85d7b21ecefc9aa3aed21c8299c89487bart
38032424fd85d7b21ecefc9aa3aed21c8299c89487bart  /* Wait until the created thread has locked s_mutex2. */
39032424fd85d7b21ecefc9aa3aed21c8299c89487bart  pthread_cond_wait(&s_cond, &s_mutex1);
40032424fd85d7b21ecefc9aa3aed21c8299c89487bart  pthread_mutex_unlock(&s_mutex1);
41032424fd85d7b21ecefc9aa3aed21c8299c89487bart
42032424fd85d7b21ecefc9aa3aed21c8299c89487bart  /* Cancel the created thread. */
43032424fd85d7b21ecefc9aa3aed21c8299c89487bart  pthread_cancel(tid);
44032424fd85d7b21ecefc9aa3aed21c8299c89487bart
45032424fd85d7b21ecefc9aa3aed21c8299c89487bart  /* Join the created thread. */
46032424fd85d7b21ecefc9aa3aed21c8299c89487bart  pthread_join(tid, 0);
47032424fd85d7b21ecefc9aa3aed21c8299c89487bart
4891d2fe224a358d3314046f8335e75b8ae47da0c0bart  /* Invoke pthread_cancel() with an invalid thread ID. */
4991d2fe224a358d3314046f8335e75b8ae47da0c0bart  pthread_cancel(tid);
5091d2fe224a358d3314046f8335e75b8ae47da0c0bart
51032424fd85d7b21ecefc9aa3aed21c8299c89487bart  fprintf(stderr, "Test finished.\n");
52032424fd85d7b21ecefc9aa3aed21c8299c89487bart
53032424fd85d7b21ecefc9aa3aed21c8299c89487bart  return 0;
54032424fd85d7b21ecefc9aa3aed21c8299c89487bart}
55