/* * Copyright (c) 2002, Intel Corporation. All rights reserved. * Created by: rolla.n.selbak REMOVE-THIS AT intel DOT com * This file is licensed under the GPL license. For the full content * of this license, see the COPYING file at the top level of this * source tree. * Test pthread_cancel * When the cancelation is acted on, the cancelation cleanup handlers for * 'thread' shall be called. * * STEPS: * 1. Create a thread * 2. In the thread function, push a cleanup function onto the stack * 3. Cancel the thread. The cleanup function should be automatically * executed, else the test will fail. */ #include #include #include #include #include "posixtest.h" int sem; /* Manual semaphore */ int cleanup_flag; /* Made global so that the cleanup function can manipulate the value as well. */ /* A cleanup function that sets the cleanup_flag to 1, meaning that the * cleanup function was reached. */ void a_cleanup_func() { cleanup_flag=1; sem=0; return; } /* A thread function called at the creation of the thread. It will push * the cleanup function onto it's stack, then go into a continuous 'while' * loop, never reaching the cleanup_pop function. So the only way the cleanup * function can be called is when the thread is canceled and all the cleanup * functions are supposed to be popped. */ void *a_thread_func() { /* To enable thread immediate cancelation, since the default * is PTHREAD_CANCEL_DEFERRED. */ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_cleanup_push(a_cleanup_func,NULL); sem=1; while(sem==1) sleep(1); sleep(5); sem=0; /* Should never be reached, but is required to be in the code * since pthread_cleanup_push is in the code. Else a compile error * will result. */ pthread_cleanup_pop(0); perror("Operation timed out, thread could not be canceled\n"); pthread_exit(0); return NULL; } int main() { pthread_t new_th; int i; /* Initializing the cleanup flag. */ cleanup_flag=0; sem=0; /* Create a new thread. */ if(pthread_create(&new_th, NULL, a_thread_func, NULL) != 0) { perror("Error creating thread\n"); return PTS_UNRESOLVED; } /* Make sure thread is created before we cancel it. */ while(sem==0) sleep(1); if(pthread_cancel(new_th) != 0) { printf("Error canceling thread\n"); return PTS_FAIL; } i=0; while(sem==1) { sleep(1); if(i==10) { printf("Test FAILED: Timed out while waiting for cancelation cleanup handlers to execute\n"); return PTS_FAIL; } i++; } /* If the cleanup function was not reached by calling the * pthread_cancel function, then the test fails. */ if(cleanup_flag != 1) { printf("Test FAILED: Could not cancel thread\n"); return PTS_FAIL; } printf("Test PASSED\n"); return PTS_PASS; }