summaryrefslogtreecommitdiff
path: root/misc/apr_thread_pool.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc/apr_thread_pool.c')
-rw-r--r--misc/apr_thread_pool.c64
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)) {