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