1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** Cancel a thread that holds a lock on a mutex. */
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <assert.h>
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <pthread.h>
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h>
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownpthread_cond_t  s_cond;
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownpthread_mutex_t s_mutex1;
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownpthread_mutex_t s_mutex2;
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void* thread(void* arg)
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Lock s_mutex2. */
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_mutex_lock(&s_mutex2);
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Inform the main thread that s_mutex2 has been locked, and wait for pthread_cancel(). */
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_mutex_lock(&s_mutex1);
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_cond_signal(&s_cond);
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_cond_wait(&s_cond, &s_mutex1);
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 0;
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main(int argc, char** argv)
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_t tid;
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Initialize synchronization objects. */
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_cond_init(&s_cond, 0);
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_mutex_init(&s_mutex1, 0);
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_mutex_init(&s_mutex2, 0);
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Create thread. */
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_mutex_lock(&s_mutex1);
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_create(&tid, 0, &thread, 0);
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Wait until the created thread has locked s_mutex2. */
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_cond_wait(&s_cond, &s_mutex1);
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_mutex_unlock(&s_mutex1);
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Cancel the created thread. */
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_cancel(tid);
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Join the created thread. */
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_join(tid, 0);
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fprintf(stderr, "Test finished.\n");
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 0;
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
52