in misc/apr_thread_pool.c [87:177]
static apr_status_t thread_pool_construct(apr_thread_pool_t **tp,
apr_size_t init_threads,
apr_size_t max_threads,
apr_pool_t *pool)
{
apr_status_t rv;
apr_thread_pool_t *me;
me = *tp = apr_pcalloc(pool, sizeof(apr_thread_pool_t));
me->thd_max = max_threads;
me->idle_max = init_threads;
me->threshold = init_threads / 2;
/* This pool will be used by different threads. As we cannot ensure that
* our caller won't use the pool without acquiring the mutex, we must
* create a new sub pool.
*/
rv = apr_pool_create(&me->pool, pool);
if (APR_SUCCESS != rv) {
return rv;
}
/* Create the mutex on the parent pool such that it's always alive from
* apr_thread_pool_{push,schedule,top}() callers.
*/
rv = apr_thread_mutex_create(&me->lock, APR_THREAD_MUTEX_NESTED, pool);
if (APR_SUCCESS != rv) {
return rv;
}
rv = apr_thread_cond_create(&me->more_work, me->pool);
if (APR_SUCCESS != rv) {
apr_thread_mutex_destroy(me->lock);
return rv;
}
rv = apr_thread_cond_create(&me->work_done, me->pool);
if (APR_SUCCESS != rv) {
apr_thread_cond_destroy(me->more_work);
apr_thread_mutex_destroy(me->lock);
return rv;
}
rv = apr_thread_cond_create(&me->all_done, me->pool);
if (APR_SUCCESS != rv) {
apr_thread_cond_destroy(me->work_done);
apr_thread_cond_destroy(me->more_work);
apr_thread_mutex_destroy(me->lock);
return rv;
}
me->tasks = apr_palloc(me->pool, sizeof(*me->tasks));
if (!me->tasks) {
goto CATCH_ENOMEM;
}
APR_RING_INIT(me->tasks, apr_thread_pool_task, link);
me->scheduled_tasks = apr_palloc(me->pool, sizeof(*me->scheduled_tasks));
if (!me->scheduled_tasks) {
goto CATCH_ENOMEM;
}
APR_RING_INIT(me->scheduled_tasks, apr_thread_pool_task, link);
me->recycled_tasks = apr_palloc(me->pool, sizeof(*me->recycled_tasks));
if (!me->recycled_tasks) {
goto CATCH_ENOMEM;
}
APR_RING_INIT(me->recycled_tasks, apr_thread_pool_task, link);
me->busy_thds = apr_palloc(me->pool, sizeof(*me->busy_thds));
if (!me->busy_thds) {
goto CATCH_ENOMEM;
}
APR_RING_INIT(me->busy_thds, apr_thread_list_elt, link);
me->idle_thds = apr_palloc(me->pool, sizeof(*me->idle_thds));
if (!me->idle_thds) {
goto CATCH_ENOMEM;
}
APR_RING_INIT(me->idle_thds, apr_thread_list_elt, link);
me->dead_thds = apr_palloc(me->pool, sizeof(*me->dead_thds));
if (!me->dead_thds) {
goto CATCH_ENOMEM;
}
APR_RING_INIT(me->dead_thds, apr_thread_list_elt, link);
me->recycled_thds = apr_palloc(me->pool, sizeof(*me->recycled_thds));
if (!me->recycled_thds) {
goto CATCH_ENOMEM;
}
APR_RING_INIT(me->recycled_thds, apr_thread_list_elt, link);
goto FINAL_EXIT;
CATCH_ENOMEM:
rv = APR_ENOMEM;
apr_thread_cond_destroy(me->all_done);
apr_thread_cond_destroy(me->work_done);
apr_thread_cond_destroy(me->more_work);
apr_thread_mutex_destroy(me->lock);
FINAL_EXIT:
return rv;
}