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