#include "deferred_cancellation.h" void memory_cleanup_handler(void* arg) { printf("%s invoked ...\n", __FUNCTION__); free(arg); } void file_cleanup_handler(void* arg) { printf("%s invoked ...\n", __FUNCTION__); fclose((FILE*)arg); } void* write_into_file(void* arg) { char file_name[64]; char string_to_write[64]; int len; int count = 0; /* Mark the thread eligible for cancellation */ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE /*PTHREAD_CANCEL_DISABLE*/, 0); /* Mode of cancellation */ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0); int* thread_id = (int*)arg; /* When pthread_cancel is invoked and this thread get the signal to get cancelled, this API is invoked to free up the resources used by this thread.*/ pthread_cleanup_push(memory_cleanup_handler, arg); sprintf(file_name, "thread_%d.txt", *thread_id); FILE* fptr = fopen(file_name, "w"); pthread_cleanup_push(file_cleanup_handler, fptr); if (!fptr) { printf("Error : Could not open log file %s, errno = %d\n", file_name, errno); pthread_exit(0); } while (1) { len = sprintf(string_to_write, "%d : I'm thread %d\n", count++, *thread_id); fwrite(string_to_write, sizeof(char), len, fptr); fflush(fptr); sleep(1); /* After sleep, this API call check if there is any cancel signal pending to this thread and invoke the cleanup handler if there is some cancellation signal pending to this thread and then cancel the thread. It works only when the cancellation type of this thread is set to DEFERRED.*/ pthread_testcancel(); } /* If this thread is successfully executed and the cancellation request is not invoked till now then, the stack where resource free API are need to be cleaned.*/ pthread_cleanup_pop(0); pthread_cleanup_pop(0); /*This is not executed as this thread is in infinite loop and when the pthread_cancel is executed this thread is cancelled while it was executing in the loop. Hence, this causes resource leakage.*/ // fclose(fptr); return 0; }