/* The gtthread_exit() function is analogous to pthread_exit. */ void gtthread_exit(void* retval) { sigprocmask(SIG_BLOCK, &vtalrm, NULL); gtthread_t *thread = steque_front(&g_threads_steque); thread->is_finished = 1; if(retval != NULL) thread->retval = retval; /* If this was the last thread in the queue, clean up and exit */ if(steque_size(&g_threads_steque) == 1) { gtthread_t *dead_thread; int num = steque_size(&g_dead_threads_steque); while(num > 0) { dead_thread = steque_front(&g_dead_threads_steque); if(dead_thread->context && dead_thread->context->uc_stack.ss_sp) free(dead_thread->context->uc_stack.ss_sp); if(dead_thread->context) free(dead_thread->context); if(dead_thread->id == 0) free(dead_thread); if(steque_size(&g_dead_threads_steque) > 1) steque_cycle(&g_dead_threads_steque); num--; } if(thread->context) free(thread->context); // Main thread was the only one that was dynamically allocated. if(thread->id == 0) free(thread); steque_destroy(&g_threads_steque); steque_destroy(&g_dead_threads_steque); steque_destroy(&g_cancelatorium); steque_destroy(&g_join_steque); /* So apparently we can't free the stack of the thread that is running. */ // if(thread->context && thread->context->uc_stack.ss_sp) // free(thread->context->uc_stack.ss_sp); exit(0); } sigprocmask(SIG_UNBLOCK, &vtalrm, NULL); alarm_safe_yield(); }
static void _sig_handler(int signo){ int shm_segnum; char shm_segid[SEGID_LEN]; if (signo == SIGINT || signo == SIGTERM){ fprintf(stderr, "Received KILL signal\n"); /* Free the queue */ pthread_mutex_lock(&sq_mtx); steque_destroy(&shm_segnum_queue); pthread_mutex_unlock(&sq_mtx); /* Clean up mutex and condition variables */ // pthread_mutex_destroy(&sq_mtx); // pthread_cond_destroy(&sq_notempty); /* Remove shared memory segments */ for (shm_segnum = 0; shm_segnum < shm_segcount; shm_segnum++) { /* Unlink shared memory ids and mark them for deletion */ sprintf(shm_segid, "/%d", shm_segnum); shm_unlink(shm_segid); fprintf(stderr, "[_sig_handler] Terminated shm_segid %s\n", shm_segid); } /* Close and unlink message queue */ close(mqd); mq_unlink(mq_name); fprintf(stderr, "[_sig_handler] Terminated message queue %s\n", mq_name); gfserver_stop(&gfs); exit(signo); } }
/* The gtthread_exit() function is analogous to pthread_exit. */ void gtthread_exit(void* retval) { int flag = 0, i = 0; //Node to be deleted steque_node_t* temp = q->front; void* exit_item = steque_front(q); block_signal(); //Setting the canceled flag and return value ((node_t*)exit_item) -> returns = retval; ((node_t*)exit_item) -> canceled = 1; //Check if this is the only executing thread. Exit. for (i = 0; (i < q->N); i++) { if(((node_t*)temp -> item) -> canceled == 0){ flag = 1 ; break; } temp = temp -> next; } if(flag == 0){ steque_destroy(q); exit(0); } unblock_signal(); raise(SIGVTALRM); }
void CleanupThreads() { printf("Cleaning thread...\n"); _threadsAlive = 0; steque_destroy(_queue); free(_queue); printf("Thread cleaned successfully\n"); }
void gtcache_destroy(){ int i; for (i = 0; i < cache.max_entries; i++) { if (cache.entries[i].size > 0) { free(cache.entries[i].data); free(cache.entries[i].url); } } free(cache.entries); steque_destroy(&free_ids); indexminpq_destroy(&id_by_time_pq); hshtbl_destroy(&url_to_id_tbl); }