APU_DECLARE(apr_status_t) apr_thread_pool_create(apr_thread_pool_t ** me, apr_size_t init_threads, apr_size_t max_threads, apr_pool_t * pool) { apr_thread_t *t; apr_status_t rv = APR_SUCCESS; apr_thread_pool_t *tp; *me = NULL; tp = apr_pcalloc(pool, sizeof(apr_thread_pool_t)); /* * 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(&tp->pool, pool); if (APR_SUCCESS != rv) return rv; rv = thread_pool_construct(tp, init_threads, max_threads); if (APR_SUCCESS != rv) return rv; apr_pool_pre_cleanup_register(tp->pool, tp, thread_pool_cleanup); while (init_threads) { /* Grab the mutex as apr_thread_create() and thread_pool_func() will * allocate from (*me)->pool. This is dangerous if there are multiple * initial threads to create. */ apr_thread_mutex_lock(tp->lock); ++tp->spawning_cnt; rv = apr_thread_create(&t, NULL, thread_pool_func, tp, tp->pool); apr_thread_mutex_unlock(tp->lock); if (APR_SUCCESS != rv) { break; } tp->thd_cnt++; if (tp->thd_cnt > tp->thd_high) { tp->thd_high = tp->thd_cnt; } --init_threads; } if (rv == APR_SUCCESS) { *me = tp; } return rv; }
APU_DECLARE(apr_status_t) apr_thread_pool_create(apr_thread_pool_t ** me, apr_size_t init_threads, apr_size_t max_threads, apr_pool_t * pool) { apr_thread_t *t; apr_status_t rv = APR_SUCCESS; *me = apr_pcalloc(pool, sizeof(**me)); if (!*me) { return APR_ENOMEM; } (*me)->pool = pool; rv = thread_pool_construct(*me, init_threads, max_threads); if (APR_SUCCESS != rv) { *me = NULL; return rv; } apr_pool_cleanup_register(pool, *me, thread_pool_cleanup, apr_pool_cleanup_null); while (init_threads) { rv = apr_thread_create(&t, NULL, thread_pool_func, *me, (*me)->pool); if (APR_SUCCESS != rv) { break; } ++(*me)->thd_cnt; if ((*me)->thd_cnt > (*me)->thd_high) (*me)->thd_high = (*me)->thd_cnt; --init_threads; } return rv; }