diff --git a/include/ldap_pvt_thread.h b/include/ldap_pvt_thread.h index 23529a9758..2f4332607d 100644 --- a/include/ldap_pvt_thread.h +++ b/include/ldap_pvt_thread.h @@ -319,6 +319,15 @@ ldap_pvt_thread_pool_destroy LDAP_P(( ldap_pvt_thread_pool_t *pool, int run_pending )); +LDAP_F( int ) +ldap_pvt_thread_pool_close LDAP_P(( + ldap_pvt_thread_pool_t *pool, + int run_pending )); + +LDAP_F( int ) +ldap_pvt_thread_pool_free LDAP_P(( + ldap_pvt_thread_pool_t *pool )); + LDAP_F( int ) ldap_pvt_thread_pool_getkey LDAP_P(( void *ctx, diff --git a/libraries/libldap_r/ldap_thr_debug.h b/libraries/libldap_r/ldap_thr_debug.h index b42db34925..d3c3617f65 100644 --- a/libraries/libldap_r/ldap_thr_debug.h +++ b/libraries/libldap_r/ldap_thr_debug.h @@ -135,6 +135,8 @@ */ #undef ldap_pvt_thread_pool_destroy #define ldap_pvt_thread_pool_destroy(p,r) ldap_int_thread_pool_destroy(p,r) +#define ldap_pvt_thread_pool_close(p,r) ldap_int_thread_pool_close(p,r) +#define ldap_pvt_thread_pool_free(p) ldap_int_thread_pool_free(p) #endif #ifdef LDAP_THREAD_DEBUG_IMPLEMENTATION /* thr_debug.c */ diff --git a/libraries/libldap_r/thr_debug.c b/libraries/libldap_r/thr_debug.c index 19a11bf485..36ce8f57c8 100644 --- a/libraries/libldap_r/thr_debug.c +++ b/libraries/libldap_r/thr_debug.c @@ -1220,6 +1220,36 @@ ldap_pvt_thread_pool_destroy( ldap_pvt_thread_pool_t *tpool, int run_pending ) return rc; } +int +ldap_pvt_thread_pool_close( ldap_pvt_thread_pool_t *tpool, int run_pending ) +{ + int rc, has_pool; + ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_close" ); + has_pool = (tpool && *tpool); + rc = ldap_int_thread_pool_close( tpool, run_pending ); + if( has_pool && rc ) { + ERROR( rc, "ldap_pvt_thread_pool_close" ); + } + return rc; +} + +int +ldap_pvt_thread_pool_free( ldap_pvt_thread_pool_t *tpool ) +{ + int rc, has_pool; + ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_free" ); + has_pool = (tpool && *tpool); + rc = ldap_int_thread_pool_free( tpool ); + if( has_pool ) { + if( rc ) { + ERROR( rc, "ldap_pvt_thread_pool_free" ); + } else { + adjust_count( Idx_tpool, -1 ); + } + } + return rc; +} + int ldap_pvt_thread_pool_pause( ldap_pvt_thread_pool_t *tpool ) { diff --git a/libraries/libldap_r/thr_stub.c b/libraries/libldap_r/thr_stub.c index 6f877fceb9..a037965c6b 100644 --- a/libraries/libldap_r/thr_stub.c +++ b/libraries/libldap_r/thr_stub.c @@ -218,6 +218,19 @@ ldap_pvt_thread_pool_destroy ( return(0); } +int +ldap_pvt_thread_pool_close ( + ldap_pvt_thread_pool_t *pool, int run_pending ) +{ + return(0); +} + +int +ldap_pvt_thread_pool_free ( ldap_pvt_thread_pool_t *pool ) +{ + return(0); +} + void ldap_pvt_thread_pool_idle ( ldap_pvt_thread_pool_t *pool ) { diff --git a/libraries/libldap_r/tpool.c b/libraries/libldap_r/tpool.c index d28e96491b..8d79184ca6 100644 --- a/libraries/libldap_r/tpool.c +++ b/libraries/libldap_r/tpool.c @@ -443,7 +443,7 @@ ldap_pvt_thread_pool_submit2 ( */ ldap_int_thread_task_t *ptr; - /* let pool_destroy know there are no more threads */ + /* let pool_close know there are no more threads */ ldap_pvt_thread_cond_signal(&pq->ltp_cond); LDAP_STAILQ_FOREACH(ptr, &pq->ltp_pending_list, ltt_next.q) @@ -771,9 +771,26 @@ ldap_pvt_thread_pool_backload ( ldap_pvt_thread_pool_t *tpool ) return rc; } -/* Destroy the pool after making its threads finish */ + +/* + * wrapper for ldap_pvt_thread_pool_close+free(), left around + * for backwards compatibility + */ int ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t *tpool, int run_pending ) +{ + int rc; + + if ( (rc = ldap_pvt_thread_pool_close( tpool, run_pending )) ) { + return rc; + } + + return ldap_pvt_thread_pool_free( tpool ); +} + +/* Shut down the pool making its threads finish */ +int +ldap_pvt_thread_pool_close ( ldap_pvt_thread_pool_t *tpool, int run_pending ) { struct ldap_int_thread_pool_s *pool, *pptr; struct ldap_int_thread_poolq_s *pq; @@ -790,9 +807,6 @@ ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t *tpool, int run_pending ) ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex); LDAP_STAILQ_FOREACH(pptr, &ldap_int_thread_pool_list, ltp_next) if (pptr == pool) break; - if (pptr == pool) - 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); if (pool != pptr) return(-1); @@ -830,18 +844,49 @@ ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t *tpool, int run_pending ) LDAP_FREE(task); } ldap_pvt_thread_mutex_unlock(&pq->ltp_mutex); - ldap_pvt_thread_cond_destroy(&pq->ltp_cond); - ldap_pvt_thread_mutex_destroy(&pq->ltp_mutex); } + return(0); +} + +/* Destroy the pool, everything must have already shut down */ +int +ldap_pvt_thread_pool_free ( ldap_pvt_thread_pool_t *tpool ) +{ + struct ldap_int_thread_pool_s *pool, *pptr; + struct ldap_int_thread_poolq_s *pq; + int i; + + if (tpool == NULL) + return(-1); + + pool = *tpool; + + if (pool == NULL) return(-1); + + ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex); + LDAP_STAILQ_FOREACH(pptr, &ldap_int_thread_pool_list, ltp_next) + if (pptr == pool) break; + if (pptr == pool) + 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); + + if (pool != pptr) return(-1); + ldap_pvt_thread_cond_destroy(&pool->ltp_pcond); ldap_pvt_thread_cond_destroy(&pool->ltp_cond); ldap_pvt_thread_mutex_destroy(&pool->ltp_mutex); for (i=0; iltp_numqs; i++) { pq = pool->ltp_wqs[i]; + + assert( !pq->ltp_open_count ); + assert( LDAP_SLIST_EMPTY(&pq->ltp_free_list) ); if (pq->ltp_free) { LDAP_FREE(pq->ltp_free); } + ldap_pvt_thread_cond_destroy(&pq->ltp_cond); + ldap_pvt_thread_mutex_destroy(&pq->ltp_mutex); } LDAP_FREE(pool->ltp_wqs); LDAP_FREE(pool);