]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#8850 Split ldap_pvt_thread_pool_destroy logic
authorOndřej Kuzník <ondra@openldap.org>
Wed, 9 May 2018 15:05:30 +0000 (16:05 +0100)
committerOndřej Kuzník <ondra@openldap.org>
Fri, 19 Oct 2018 12:08:09 +0000 (13:08 +0100)
include/ldap_pvt_thread.h
libraries/libldap_r/ldap_thr_debug.h
libraries/libldap_r/thr_debug.c
libraries/libldap_r/thr_stub.c
libraries/libldap_r/tpool.c

index 23529a975871599250318eb782f6ea8bf47440b9..2f4332607d20a58ce104d71597ec414e8cb1aa94 100644 (file)
@@ -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,
index b42db34925ab02288ccc47ccc92e786107c284cf..d3c3617f652d8c1fcae391d5a53ba604f8eded86 100644 (file)
  */
 #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 */
index 19a11bf48517bea8c1c7aeb9e26490f22b78a1dd..36ce8f57c8869fbd22de3a6f5080a141545c0da1 100644 (file)
@@ -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 )
 {
index 6f877fceb9a67c8cee2713cb03403a0046410557..a037965c6b8d6b7ae19028a371b1e4fe0f6b91f1 100644 (file)
@@ -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 )
 {
index d28e96491b8a77cfb07bc8003f9a3f3463d2b2e8..8d79184ca69423f34f3cefef0c49e8b5b83ecce3 100644 (file)
@@ -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; i<pool->ltp_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);