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;
}
Esempio n. 2
0
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;
}