1/* 2 * Copyright (c) 2002, Intel Corporation. All rights reserved. 3 * Created by: rolla.n.selbak REMOVE-THIS AT intel DOT com 4 * This file is licensed under the GPL license. For the full content 5 * of this license, see the COPYING file at the top level of this 6 * source tree. 7 8 * Test pthread_setcanceltype 9 * Atomically sets the cancelability type to 'type' and returns the old 10 * cancelability type in the location referenced by 'oldtype'. 11 * 'state' can either be PTHREAD_CANCEL_DEFERRED, or PTHREAD_CANCEL_ASYNCHRONOUS. 12 * 13 * Test when a thread is PTHREAD_CANCEL_DEFERRED 14 * 15 * STEPS: 16 * 1. Setup a mutex and lock it in main() 17 * 2. Create a thread. 18 * 3. In the thread function, set the type to PTHREAD_CANCEL_DEFERRED 19 * 4. Setup a cleanup handler for the thread. 20 * 5. Make the thread block on the locked mutex 21 * 6. Send out a thread cancel request to the new thread, and unlock the mutex allowing the 22 * thread to continue execution. 23 * 7. If the cancel request was honored immediately, the 24 * cleanup handler would have been executed, setting the cleanup_flag to -1, making the 25 * test fail. 26 * 8. If not, the thread will continue execution, pop the cleanup handler, set the cleanup 27 * flag to 1, and call the cancelation point pthread_testcancel(). The test will pass. 28 * 9. If the thread did not cancel at the cancelation point like it was supposed to, the thread 29 * will continue execution and set the cleanup_flag to -2, failing the test. 30 */ 31 32#include <pthread.h> 33#include <stdio.h> 34#include <errno.h> 35#include <unistd.h> 36#include "posixtest.h" 37 38# define INTHREAD 0 /* Control going to or is already for Thread */ 39# define INMAIN 1 /* Control going to or is already for Main */ 40 41int sem1; /* Manual semaphore */ 42int cleanup_flag; /* Flag to indicate the thread's cleanup handler was called */ 43pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /* Mutex */ 44 45 46/* Cleanup function that the thread executes when it is canceled. So if 47 * cleanup_flag is 1, it means that the thread was canceled. */ 48void a_cleanup_func() 49{ 50 cleanup_flag=-1; 51 return; 52} 53 54/* Function that the thread executes upon its creation */ 55void *a_thread_func() 56{ 57 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 58 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); 59 60 pthread_cleanup_push(a_cleanup_func,NULL); 61 62 /* Indicate to main() that the thread has been created. */ 63 sem1=INMAIN; 64 65 /* Lock the mutex. It should have already been locked in main, so the thread 66 * should block. */ 67 if(pthread_mutex_lock(&mutex) != 0) 68 { 69 perror("Error in pthread_mutex_lock()\n"); 70 pthread_exit((void*)PTS_UNRESOLVED); 71 return (void*)PTS_UNRESOLVED; 72 } 73 74 /* Should get here if the cancel request was deffered. */ 75 pthread_cleanup_pop(0); 76 cleanup_flag=1; 77 78 /* Cancelation point. Cancel request should not be honored here. */ 79 pthread_testcancel(); 80 81 /* Should not get here if the cancel request was honored at the cancelation point 82 * pthread_testcancel(). */ 83 cleanup_flag=-2; 84 pthread_exit(0); 85 return NULL; 86} 87 88int main() 89{ 90 pthread_t new_th; 91 92 /* Initializing values */ 93 sem1=INTHREAD; 94 cleanup_flag=0; 95 96 /* Lock the mutex */ 97 if(pthread_mutex_lock(&mutex) != 0) 98 { 99 perror("Error in pthread_mutex_lock()\n"); 100 return PTS_UNRESOLVED; 101 } 102 103 /* Create a new thread. */ 104 if(pthread_create(&new_th, NULL, a_thread_func, NULL) != 0) 105 { 106 perror("Error creating thread\n"); 107 return PTS_UNRESOLVED; 108 } 109 110 /* Make sure thread is created before we cancel it. (wait for 111 * a_thread_func() to set sem1=INMAIN.) */ 112 while(sem1==INTHREAD) 113 sleep(1); 114 115 /* Send cancel request to the thread. */ 116 if(pthread_cancel(new_th) != 0) 117 { 118 printf("Test FAILED: Couldn't cancel thread\n"); 119 return PTS_FAIL; 120 } 121 122 /* Cancel request has been sent, unlock the mutex */ 123 if(pthread_mutex_unlock(&mutex) != 0) 124 { 125 perror("Error in pthread_mutex_unlock()\n"); 126 return PTS_UNRESOLVED; 127 } 128 129 /* Wait 'till the thread has been canceled or has ended execution. */ 130 if(pthread_join(new_th, NULL) != 0) 131 { 132 perror("Error in pthread_join()\n"); 133 return PTS_UNRESOLVED; 134 } 135 136 /* This means that the cleanup function wasn't called, so the cancel 137 * request was not honord immediately like it should have been. */ 138 if(cleanup_flag == -1) 139 { 140 printf("Test FAILED: Cancel request was not deferred.\n"); 141 return PTS_FAIL; 142 } 143 144 if(cleanup_flag == -2) 145 { 146 printf("Test FAILED: (1) Cancel request not honored at cancelation point pthread_testcancel() OR (2) pthread_testcancel() not treated as a cancelation point.\n"); 147 return PTS_FAIL; 148 } 149 150 printf("Test PASSED\n"); 151 return PTS_PASS; 152} 153 154 155