]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap_r/tpool.c
further clarify size limit related issues in sync replication (ITS#5243)
[openldap] / libraries / libldap_r / tpool.c
index 355543cd3e186fe6f505920b1e3aa5379376454a..e862da6c224d314a74cc1c666291324f8a119de7 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2006 The OpenLDAP Foundation.
+ * Copyright 1998-2007 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -111,7 +111,6 @@ ldap_int_thread_pool_shutdown ( void )
        struct ldap_int_thread_pool_s *pool;
 
        while ((pool = LDAP_STAILQ_FIRST(&ldap_int_thread_pool_list)) != NULL) {
-               LDAP_STAILQ_REMOVE_HEAD(&ldap_int_thread_pool_list, ltp_next);
                (ldap_pvt_thread_pool_destroy)(&pool, 0); /* ignore thr_debug macro */
        }
        ldap_pvt_thread_mutex_destroy(&ldap_pvt_thread_pool_mutex);
@@ -353,7 +352,6 @@ int
 ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t *tpool, int run_pending )
 {
        struct ldap_int_thread_pool_s *pool, *pptr;
-       long waiting;
        ldap_int_thread_ctx_t *ctx;
 
        if (tpool == NULL)
@@ -378,8 +376,11 @@ ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t *tpool, int run_pending )
                ? LDAP_INT_THREAD_POOL_FINISHING
                : LDAP_INT_THREAD_POOL_STOPPING;
 
-       ldap_pvt_thread_cond_broadcast(&pool->ltp_cond);
-       ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex);
+       if ( pool->ltp_open_count ) {
+               ldap_pvt_thread_cond_broadcast(&pool->ltp_cond);
+               ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex);
+       }
+       ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
 
        while ((ctx = LDAP_STAILQ_FIRST(&pool->ltp_pending_list)) != NULL)
        {
@@ -490,12 +491,7 @@ ldap_int_thread_pool_wrapper (
                }
        }
 
-       for ( i=0; i<MAXKEYS && ltc_key[i].ltk_key; i++ ) {
-               if (ltc_key[i].ltk_free)
-                       ltc_key[i].ltk_free(
-                               ltc_key[i].ltk_key,
-                               ltc_key[i].ltk_data );
-       }
+       ldap_pvt_thread_pool_context_reset( ltc_key );
 
        thread_keys[keyslot].ctx = NULL;
        thread_keys[keyslot].id = tid_zero;
@@ -600,10 +596,25 @@ int ldap_pvt_thread_pool_setkey(
        if ( !ctx || !key ) return EINVAL;
 
        for ( i=0; i<MAXKEYS; i++ ) {
-               if ( !ctx[i].ltk_key || ctx[i].ltk_key == key ) {
-                       ctx[i].ltk_key = key;
-                       ctx[i].ltk_data = data;
-                       ctx[i].ltk_free = kfree;
+               if (( data && !ctx[i].ltk_key ) || ctx[i].ltk_key == key ) {
+                       if ( data || kfree ) {
+                               ctx[i].ltk_key = key;
+                               ctx[i].ltk_data = data;
+                               ctx[i].ltk_free = kfree;
+                       } else {
+                               int j;
+                               for ( j=i+1; j<MAXKEYS; j++ )
+                                       if ( !ctx[j].ltk_key ) break;
+                               j--;
+                               if ( j != i ) {
+                                       ctx[i].ltk_key = ctx[j].ltk_key;
+                                       ctx[i].ltk_data = ctx[j].ltk_data;
+                                       ctx[i].ltk_free = ctx[j].ltk_free;
+                               }
+                               ctx[j].ltk_key = NULL;
+                               ctx[j].ltk_data = NULL;
+                               ctx[j].ltk_free = NULL;
+                       }
                        return 0;
                }
        }
@@ -664,7 +675,9 @@ void ldap_pvt_thread_pool_context_reset( void *vctx )
        ldap_int_thread_key_t *ctx = vctx;
        int i;
 
-       for ( i=0; i<MAXKEYS && ctx[i].ltk_key; i++) {
+       for ( i=MAXKEYS-1; i>=0; i--) {
+               if ( ctx[i].ltk_key == NULL )
+                       continue;
                if ( ctx[i].ltk_free )
                        ctx[i].ltk_free( ctx[i].ltk_key, ctx[i].ltk_data );
                ctx[i].ltk_key = NULL;