void cp_heap_destroy(cp_heap *h) { #ifdef __TRACE__ DEBUGMSG("cp_heap_destroy\n"); heap_info(h); #endif if (h) { if (h->heap) { if ((h->mode & COLLECTION_MODE_DEEP) && h->dtr) { int i; for (i = 1; i < h->heap_end; ++i) if (h->heap[i]) (*h->dtr)(h->heap[i]); } free(h->heap); } if (h->lock) { cp_mutex_destroy(h->lock); free(h->lock); } free(h); } }
cp_pooled_thread *cp_pooled_thread_create(cp_thread_pool *owner) { int rc; cp_pooled_thread *pt = calloc(1, sizeof(cp_pooled_thread)); if (pt == NULL) { cp_error(CP_MEMORY_ALLOCATION_FAILURE, "can\'t allocate pooled thread"); errno = ENOMEM; return NULL; } pt->worker = calloc(1, sizeof(cp_thread)); if (pt->worker == NULL) { cp_error(CP_MEMORY_ALLOCATION_FAILURE, "can\'t allocate thread"); errno = ENOMEM; return NULL; } pt->owner = owner; pt->suspend_lock = (cp_mutex *) malloc(sizeof(cp_mutex)); if (pt->suspend_lock == NULL) goto THREAD_CREATE_CANCEL; if ((rc = cp_mutex_init(pt->suspend_lock, NULL))) { cp_error(rc, "starting up pooled thread"); goto THREAD_CREATE_CANCEL; } pt->suspend_cond = (cp_cond *) malloc(sizeof(cp_cond)); if ((rc = cp_cond_init(pt->suspend_cond, NULL))) { cp_error(rc, "starting up pooled thread"); cp_mutex_destroy(pt->suspend_lock); free(pt->suspend_lock); goto THREAD_CREATE_CANCEL; } pt->done = 0; pt->wait = 1; cp_thread_create(*pt->worker, NULL, cp_pooled_thread_run, pt); pt->id = cp_pooled_thread_get_id(pt); cp_thread_detach(*pt->worker); //~~ check return pt; THREAD_CREATE_CANCEL: free(pt->worker); free(pt); return NULL; }
void cp_pooled_thread_destroy(cp_pooled_thread *t) { #ifdef __TRACE__ DEBUGMSG("destroying cp_pooled_thread %lX", t); #endif cp_mutex_destroy(t->suspend_lock); free(t->suspend_lock); cp_cond_destroy(t->suspend_cond); free(t->suspend_cond); free(t->worker); free(t); }
void cp_thread_pool_destroy(cp_thread_pool *pool) { #ifdef __TRACE__ DEBUGMSG("stopping cp_thread_pool %lX", pool); #endif if (pool->running) cp_thread_pool_stop(pool); cp_list_destroy(pool->free_pool); // cp_list_destroy_custom(pool->free_pool, // (cp_destructor_fn) cp_pooled_thread_destroy); cp_hashlist_destroy(pool->in_use); // cp_hashlist_destroy_custom(pool->in_use, NULL, // (cp_destructor_fn) cp_pooled_thread_destroy); cp_mutex_destroy(pool->pool_lock); free(pool->pool_lock); cp_cond_destroy(pool->pool_cond); free(pool->pool_cond); free(pool); }
cp_thread_pool *cp_thread_pool_create(int min_size, int max_size) { int rc; cp_thread_pool *pool = calloc(1, sizeof(cp_thread_pool)); if (pool == NULL) cp_fatal(CP_MEMORY_ALLOCATION_FAILURE, "can\'t allocate thread pool structure"); pool->min_size = min_size; pool->max_size = max_size; pool->running = 1; pool->free_pool = cp_list_create(); if (pool->free_pool == NULL) cp_fatal(CP_MEMORY_ALLOCATION_FAILURE, "can\'t allocate thread pool list"); pool->in_use = cp_hashlist_create(10, cp_hash_long, cp_hash_compare_long); if (pool->in_use == NULL) cp_fatal(CP_MEMORY_ALLOCATION_FAILURE, "can\'t allocate thread pool running list"); pool->pool_lock = (cp_mutex *) malloc(sizeof(cp_mutex)); if (pool->pool_lock == NULL) { cp_error(CP_MEMORY_ALLOCATION_FAILURE, "can\'t create mutex"); goto THREAD_POOL_CREATE_CANCEL; } if ((rc = cp_mutex_init(pool->pool_lock, NULL))) { cp_error(rc, "can\'t create mutex"); goto THREAD_POOL_CREATE_CANCEL; } pool->pool_cond = (cp_cond *) malloc(sizeof(cp_cond)); if (pool->pool_cond == NULL) { cp_error(rc, "can\'t create condition variable"); cp_mutex_destroy(pool->pool_lock); free(pool->pool_lock); goto THREAD_POOL_CREATE_CANCEL; } if ((rc = cp_cond_init(pool->pool_cond, NULL))) { cp_error(rc, "can\'t create condition variable"); free(pool->pool_cond); cp_mutex_destroy(pool->pool_lock); free(pool->pool_lock); goto THREAD_POOL_CREATE_CANCEL; } for ( ; pool->size < pool->min_size; pool->size++) { cp_pooled_thread *pt = cp_pooled_thread_create(pool); if (pt == NULL) cp_fatal(CP_THREAD_CREATION_FAILURE, "can\'t create thread pool (created %d threads, minimum pool size is %d", pool->size, pool->min_size); cp_list_append(pool->free_pool, pt); } return pool; THREAD_POOL_CREATE_CANCEL: cp_list_destroy_custom(pool->free_pool, (cp_destructor_fn) cp_pooled_thread_destroy); cp_hashlist_destroy_custom(pool->in_use, NULL, (cp_destructor_fn) cp_pooled_thread_destroy); free(pool); return NULL; }