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