diff options
Diffstat (limited to 'misc/apr_thread_pool.c')
-rw-r--r-- | misc/apr_thread_pool.c | 64 |
1 files changed, 28 insertions, 36 deletions
diff --git a/misc/apr_thread_pool.c b/misc/apr_thread_pool.c index 693518d1..01c2e21d 100644 --- a/misc/apr_thread_pool.c +++ b/misc/apr_thread_pool.c @@ -72,7 +72,6 @@ struct apr_thread_pool struct apr_thread_list *busy_thds; struct apr_thread_list *idle_thds; apr_thread_mutex_t *lock; - apr_thread_mutex_t *cond_lock; apr_thread_cond_t *cond; volatile int terminated; struct apr_thread_pool_tasks *recycled_tasks; @@ -95,16 +94,9 @@ static apr_status_t thread_pool_construct(apr_thread_pool_t * me, if (APR_SUCCESS != rv) { return rv; } - rv = apr_thread_mutex_create(&me->cond_lock, APR_THREAD_MUTEX_UNNESTED, - me->pool); - if (APR_SUCCESS != rv) { - apr_thread_mutex_destroy(me->lock); - return rv; - } rv = apr_thread_cond_create(&me->cond, me->pool); if (APR_SUCCESS != rv) { apr_thread_mutex_destroy(me->lock); - apr_thread_mutex_destroy(me->cond_lock); return rv; } me->tasks = apr_palloc(me->pool, sizeof(*me->tasks)); @@ -148,7 +140,6 @@ static apr_status_t thread_pool_construct(apr_thread_pool_t * me, CATCH_ENOMEM: rv = APR_ENOMEM; apr_thread_mutex_destroy(me->lock); - apr_thread_mutex_destroy(me->cond_lock); apr_thread_cond_destroy(me->cond); FINAL_EXIT: return rv; @@ -246,7 +237,6 @@ static struct apr_thread_list_elt *elt_new(apr_thread_pool_t * me, */ static void *APR_THREAD_FUNC thread_pool_func(apr_thread_t * t, void *param) { - apr_status_t rv = APR_SUCCESS; apr_thread_pool_t *me = param; apr_thread_pool_task_t *task = NULL; apr_interval_time_t wait; @@ -321,16 +311,12 @@ static void *APR_THREAD_FUNC thread_pool_func(apr_thread_t * t, void *param) else wait = -1; - apr_thread_mutex_unlock(me->lock); - apr_thread_mutex_lock(me->cond_lock); if (wait >= 0) { - rv = apr_thread_cond_timedwait(me->cond, me->cond_lock, wait); + apr_thread_cond_timedwait(me->cond, me->lock, wait); } else { - rv = apr_thread_cond_wait(me->cond, me->cond_lock); + apr_thread_cond_wait(me->cond, me->lock); } - apr_thread_mutex_unlock(me->cond_lock); - apr_thread_mutex_lock(me->lock); } /* idle thread been asked to stop, will be joined */ @@ -342,16 +328,15 @@ static void *APR_THREAD_FUNC thread_pool_func(apr_thread_t * t, void *param) static apr_status_t thread_pool_cleanup(void *me) { - apr_thread_pool_t *_self = me; + apr_thread_pool_t *_myself = me; - _self->terminated = 1; - apr_thread_pool_idle_max_set(_self, 0); - while (_self->thd_cnt) { + _myself->terminated = 1; + apr_thread_pool_idle_max_set(_myself, 0); + while (_myself->thd_cnt) { apr_sleep(20 * 1000); /* spin lock with 20 ms */ } - apr_thread_mutex_destroy(_self->lock); - apr_thread_mutex_destroy(_self->cond_lock); - apr_thread_cond_destroy(_self->cond); + apr_thread_mutex_destroy(_myself->lock); + apr_thread_cond_destroy(_myself->cond); return APR_SUCCESS; } @@ -367,17 +352,28 @@ APU_DECLARE(apr_status_t) apr_thread_pool_create(apr_thread_pool_t ** me, *me = NULL; tp = apr_pcalloc(pool, sizeof(apr_thread_pool_t)); - tp->pool = pool; - + /* + * 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) { + if (APR_SUCCESS != rv) return rv; - } - apr_pool_cleanup_register(pool, tp, thread_pool_cleanup, + apr_pool_cleanup_register(tp->pool, tp, thread_pool_cleanup, apr_pool_cleanup_null); 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); rv = apr_thread_create(&t, NULL, thread_pool_func, tp, tp->pool); + apr_thread_mutex_unlock(tp->lock); if (APR_SUCCESS != rv) { break; } @@ -524,10 +520,8 @@ static apr_status_t schedule_task(apr_thread_pool_t *me, me->thd_high = me->thd_cnt; } } - apr_thread_mutex_unlock(me->lock); - apr_thread_mutex_lock(me->cond_lock); apr_thread_cond_signal(me->cond); - apr_thread_mutex_unlock(me->cond_lock); + apr_thread_mutex_unlock(me->lock); return rv; } @@ -579,11 +573,9 @@ static apr_status_t add_task(apr_thread_pool_t *me, apr_thread_start_t func, me->thd_high = me->thd_cnt; } } - apr_thread_mutex_unlock(me->lock); - apr_thread_mutex_lock(me->cond_lock); apr_thread_cond_signal(me->cond); - apr_thread_mutex_unlock(me->cond_lock); + apr_thread_mutex_unlock(me->lock); return rv; } @@ -841,9 +833,9 @@ static apr_size_t trim_idle_threads(apr_thread_pool_t *me, apr_size_t cnt) elt = trim_threads(me, &cnt, 1); - apr_thread_mutex_lock(me->cond_lock); + apr_thread_mutex_lock(me->lock); apr_thread_cond_broadcast(me->cond); - apr_thread_mutex_unlock(me->cond_lock); + apr_thread_mutex_unlock(me->lock); n_dbg = 0; if (NULL != (head = elt)) { |