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 * void pthread_cleanup_push(void (*routine) (void*), void *arg); 9 * 10 * Shall push the specified cancelation cleanup handler routine onto the calling thread's 11 * cancelation cleanup stack. The cancelation cleanup handler shall be popped from the 12 * cancelation cleanup stack and invoked with the argument arg when: 13 * 14 * (a)- The thread exits (calls pthread_exit()) 15 * (b)- The thread acts upon a cancelation request 16 * (c)- the thread calls pthread_cleanup_pop() with a non-zero execution argument 17 * 18 * Testing (b) 19 * 20 * STEPS: 21 * 1. Create a thread 22 * 2. In the thread, push a cancelation handler 23 * 3. Main will cancel the thread before the thread exits 24 * 4. Verify that the cleanup handler was called 25 */ 26 27#include <pthread.h> 28#include <stdio.h> 29#include <errno.h> 30#include <unistd.h> 31#include "posixtest.h" 32 33# define CLEANUP_NOTCALLED 0 34# define CLEANUP_CALLED 1 35 36# define INTHREAD 0 /* Control going to or is already for Thread */ 37# define INMAIN 1 /* Control going to or is already for Main */ 38 39int sem1; /* Manual semaphore */ 40int cleanup_flag; 41 42/* The cleanup handler */ 43void a_cleanup_func(void *flag_val) 44{ 45 cleanup_flag = (long)flag_val; 46 sem1 = INMAIN; 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 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); 55 56 pthread_cleanup_push(a_cleanup_func, (void*) CLEANUP_CALLED); 57 58 /* Indicate to main() that the thread has been created. */ 59 sem1=INMAIN; 60 61 /* Wait until main() has sent out a cancel request, meaning until it 62 * sets sem1==INTHREAD */ 63 while(sem1==INMAIN) 64 sleep(1); 65 66 /* Give thread 10 seconds to time out. If the cancel request was not 67 * honored until now, the test is unresolved because the cancel request 68 * was not handled correctly. */ 69 sleep(10); 70 71 /* Shouldn't get here if the cancel request was honored immediately 72 * like it should have been. */ 73 pthread_cleanup_pop(0); 74 pthread_exit((void*)PTS_UNRESOLVED); 75 return NULL; 76} 77 78int main() 79{ 80 pthread_t new_th; 81 void *value_ptr; /* hold return value of thread from pthread_join */ 82 83 /* Initializing values */ 84 sem1=INTHREAD; 85 cleanup_flag=CLEANUP_NOTCALLED; 86 87 /* Create a new thread. */ 88 if(pthread_create(&new_th, NULL, a_thread_func, NULL) != 0) 89 { 90 perror("Error creating thread\n"); 91 return PTS_UNRESOLVED; 92 } 93 94 /* Make sure thread is created before we cancel it. (wait for 95 * a_thread_func() to set sem1=1.) */ 96 while(sem1==INTHREAD) 97 sleep(1); 98 99 if(pthread_cancel(new_th) != 0) 100 { 101 printf("Error: Couldn't cancel thread\n"); 102 return PTS_UNRESOLVED; 103 } 104 105 /* Indicate to the thread function that the thread cancel request 106 * has been sent to it. */ 107 sem1=INTHREAD; 108 109 /* Wait for thread to return. */ 110 if(pthread_join(new_th, &value_ptr) != 0) 111 { 112 printf("Error in pthread_join()\n"); 113 return PTS_UNRESOLVED; 114 } 115 116 /* Make sure cancellation happened correctly */ 117 if((long)value_ptr == PTS_UNRESOLVED) 118 { 119 printf("Error: cancellation not correctly handled\n"); 120 return PTS_UNRESOLVED; 121 } 122 123 /* This means that the cleanup function wasn't called, so the cancel 124 * request was not honord immediately like it should have been. */ 125 if(cleanup_flag != CLEANUP_CALLED) 126 { 127 printf("Test FAILED: Cleanup hanlder not called up cancellation\n"); 128 return PTS_FAIL; 129 } 130 131 printf("Test PASSED\n"); 132 return PTS_PASS; 133} 134 135 136