From 1b777e0ab3c0fa59b82256f2399f4674263335cf Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Mon, 7 Mar 2005 21:02:31 +0000 Subject: [PATCH] Added ldap_pvt_thread_pool_pause/resume --- include/ldap_pvt_thread.h | 8 ++++ libraries/libldap_r/tpool.c | 78 ++++++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/include/ldap_pvt_thread.h b/include/ldap_pvt_thread.h index a10bbd4c1b..3ec464a093 100644 --- a/include/ldap_pvt_thread.h +++ b/include/ldap_pvt_thread.h @@ -171,6 +171,14 @@ LDAP_F( int ) ldap_pvt_thread_pool_backload LDAP_P(( ldap_pvt_thread_pool_t *pool )); +LDAP_F( int ) +ldap_pvt_thread_pool_pause LDAP_P(( + ldap_pvt_thread_pool_t *pool )); + +LDAP_F( int ) +ldap_pvt_thread_pool_resume LDAP_P(( + ldap_pvt_thread_pool_t *pool )); + LDAP_F( int ) ldap_pvt_thread_pool_destroy LDAP_P(( ldap_pvt_thread_pool_t *pool, diff --git a/libraries/libldap_r/tpool.c b/libraries/libldap_r/tpool.c index da18a36e55..31fa541cb8 100644 --- a/libraries/libldap_r/tpool.c +++ b/libraries/libldap_r/tpool.c @@ -32,7 +32,8 @@ enum ldap_int_thread_pool_state { LDAP_INT_THREAD_POOL_RUNNING, LDAP_INT_THREAD_POOL_FINISHING, - LDAP_INT_THREAD_POOL_STOPPING + LDAP_INT_THREAD_POOL_STOPPING, + LDAP_INT_THREAD_POOL_PAUSING, }; typedef struct ldap_int_thread_key_s { @@ -74,6 +75,7 @@ struct ldap_int_thread_pool_s { LDAP_STAILQ_ENTRY(ldap_int_thread_pool_s) ltp_next; ldap_pvt_thread_mutex_t ltp_mutex; ldap_pvt_thread_cond_t ltp_cond; + ldap_pvt_thread_cond_t ltp_pcond; LDAP_STAILQ_HEAD(tcq, ldap_int_thread_ctx_s) ltp_pending_list; LDAP_SLIST_HEAD(tcl, ldap_int_thread_ctx_s) ltp_free_list; LDAP_SLIST_HEAD(tclq, ldap_int_thread_ctx_s) ltp_active_list; @@ -132,6 +134,9 @@ ldap_pvt_thread_pool_init ( if (rc != 0) return(rc); rc = ldap_pvt_thread_cond_init(&pool->ltp_cond); + if (rc != 0) + return(rc); + rc = ldap_pvt_thread_cond_init(&pool->ltp_pcond); if (rc != 0) return(rc); pool->ltp_state = LDAP_INT_THREAD_POOL_RUNNING; @@ -170,6 +175,7 @@ ldap_pvt_thread_pool_init ( LDAP_STAILQ_REMOVE(ldap_int_thread_pool_list, pool, ldap_int_thread_pool_s, ltp_next); ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex); + ldap_pvt_thread_cond_destroy(&pool->ltp_pcond); ldap_pvt_thread_cond_destroy(&pool->ltp_cond); ldap_pvt_thread_mutex_destroy(&pool->ltp_mutex); LDAP_FREE(pool); @@ -204,7 +210,8 @@ ldap_pvt_thread_pool_submit ( return(-1); ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); - if (pool->ltp_state != LDAP_INT_THREAD_POOL_RUNNING + if ((pool->ltp_state != LDAP_INT_THREAD_POOL_RUNNING && + pool->ltp_state != LDAP_INT_THREAD_POOL_PAUSING) || (pool->ltp_max_pending > 0 && pool->ltp_pending_count >= pool->ltp_max_pending)) { @@ -229,6 +236,10 @@ ldap_pvt_thread_pool_submit ( pool->ltp_pending_count++; LDAP_STAILQ_INSERT_TAIL(&pool->ltp_pending_list, ctx, ltc_next.q); + if (pool->ltp_state == LDAP_INT_THREAD_POOL_PAUSING) { + ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); + return(0); + } ldap_pvt_thread_cond_signal(&pool->ltp_cond); if ((pool->ltp_open_count <= 0 #if 0 @@ -391,6 +402,7 @@ ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t *tpool, int run_pending ) LDAP_FREE(ctx); } + ldap_pvt_thread_cond_destroy(&pool->ltp_pcond); ldap_pvt_thread_cond_destroy(&pool->ltp_cond); ldap_pvt_thread_mutex_destroy(&pool->ltp_mutex); LDAP_FREE(pool); @@ -471,6 +483,13 @@ ldap_int_thread_pool_wrapper ( ldap_int_thread_ctx_s, ltc_next.al); LDAP_SLIST_INSERT_HEAD(&pool->ltp_free_list, ctx, ltc_next.l); pool->ltp_active_count--; + + if (pool->ltp_state == LDAP_INT_THREAD_POOL_PAUSING) { + if (pool->ltp_active_count < 2) { + ldap_pvt_thread_cond_signal(&pool->ltp_pcond); + } + ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex); + } ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); ldap_pvt_thread_yield(); @@ -499,6 +518,61 @@ ldap_int_thread_pool_wrapper ( return(NULL); } +int +ldap_pvt_thread_pool_pause ( + ldap_pvt_thread_pool_t *tpool ) +{ + struct ldap_int_thread_pool_s *pool; + + if (tpool == NULL) + return(-1); + + pool = *tpool; + + if (pool == NULL) + return(0); + + ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); + + /* If someone else has already requested a pause, we have to wait */ + if (pool->ltp_state == LDAP_INT_THREAD_POOL_PAUSING) { + pool->ltp_pending_count++; + pool->ltp_active_count--; + ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex); + pool->ltp_pending_count--; + pool->ltp_active_count++; + } + /* Wait for everyone else to finish */ + pool->ltp_state = LDAP_INT_THREAD_POOL_PAUSING; + while (pool->ltp_active_count > 1) { + ldap_pvt_thread_cond_wait(&pool->ltp_pcond, &pool->ltp_mutex); + } + ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); + return(0); +} + +int +ldap_pvt_thread_pool_resume ( + ldap_pvt_thread_pool_t *tpool ) +{ + struct ldap_int_thread_pool_s *pool; + + if (tpool == NULL) + return(-1); + + pool = *tpool; + + if (pool == NULL) + return(0); + + ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); + + pool->ltp_state = LDAP_INT_THREAD_POOL_RUNNING; + ldap_pvt_thread_cond_broadcast(&pool->ltp_cond); + ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); + return(0); +} + int ldap_pvt_thread_pool_getkey( void *xctx, void *key, -- 2.39.5