]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap_r/tpool.c
tpool cleanup
[openldap] / libraries / libldap_r / tpool.c
index d65d9c40b6d3f2cdf00043b96b492f9869a3b737..c682930aa6d06c8de11f9c127f9247d73c070441 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2005 The OpenLDAP Foundation.
+ * Copyright 1998-2006 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #include <ac/errno.h>
 
 #include "ldap-int.h"
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
 #include "ldap_queue.h"
+#define LDAP_THREAD_POOL_IMPLEMENTATION
+#include "ldap_thr_debug.h"  /* May rename symbols defined below */
 
 #ifndef LDAP_THREAD_HAVE_TPOOL
 
@@ -50,11 +52,6 @@ typedef struct ldap_int_thread_key_s {
 
 static ldap_pvt_thread_t tid_zero;
 
-#ifdef HAVE_PTHREADS
-#define        TID_EQ(a,b)     pthread_equal((a),(b))
-#else
-#define        TID_EQ(a,b)     ((a) == (b))
-#endif
 static struct {
        ldap_pvt_thread_t id;
        ldap_int_thread_key_t *ctx;
@@ -114,8 +111,7 @@ 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);
+               (ldap_pvt_thread_pool_destroy)(&pool, 0); /* ignore thr_debug macro */
        }
        ldap_pvt_thread_mutex_destroy(&ldap_pvt_thread_pool_mutex);
        return(0);
@@ -246,13 +242,9 @@ ldap_pvt_thread_pool_submit (
                return(0);
        }
        ldap_pvt_thread_cond_signal(&pool->ltp_cond);
-       if ((pool->ltp_open_count <= 0
-#if 0
-                       || pool->ltp_pending_count > 1
-#endif
-                       || pool->ltp_open_count == pool->ltp_active_count)
-               && (pool->ltp_max_count <= 0
-                       || pool->ltp_open_count < pool->ltp_max_count))
+       if (pool->ltp_open_count < pool->ltp_active_count + pool->ltp_pending_count
+               && (pool->ltp_open_count < pool->ltp_max_count ||
+                       pool->ltp_max_count <= 0 ))
        {
                pool->ltp_open_count++;
                pool->ltp_starting++;
@@ -277,7 +269,7 @@ ldap_pvt_thread_pool_submit (
                         */
                        TID_HASH(thr, hash);
                        for (rc = hash & (LDAP_MAXTHR-1);
-                               !TID_EQ(thread_keys[rc].id, tid_zero);
+                               !ldap_pvt_thread_equal(thread_keys[rc].id, tid_zero);
                                rc = (rc+1) & (LDAP_MAXTHR-1));
                        thread_keys[rc].id = thr;
                } else {
@@ -360,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)
@@ -385,16 +376,12 @@ 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);
+       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);
 
-       do {
-               ldap_pvt_thread_yield();
-               ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
-               waiting = pool->ltp_open_count;
-               ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
-       } while (waiting > 0);
-
        while ((ctx = LDAP_STAILQ_FIRST(&pool->ltp_pending_list)) != NULL)
        {
                LDAP_STAILQ_REMOVE_HEAD(&pool->ltp_pending_list, ltc_next.q);
@@ -437,7 +424,8 @@ ldap_int_thread_pool_wrapper (
 
        /* store pointer to our keys */
        TID_HASH(tid, hash);
-       for (i = hash & (LDAP_MAXTHR-1); !TID_EQ(thread_keys[i].id, tid);
+       for (i = hash & (LDAP_MAXTHR-1);
+                               !ldap_pvt_thread_equal(thread_keys[i].id, tid);
                                i = (i+1) & (LDAP_MAXTHR-1));
        thread_keys[i].ctx = ltc_key;
        keyslot = i;
@@ -467,6 +455,9 @@ ldap_int_thread_pool_wrapper (
                         * should be like this:
                         *   if (pool->ltp_open_count > 1 && pool->ltp_starting == 0)
                         *       check timer, leave thread (break;)
+                        *
+                        * Just use pthread_cond_timedwait if we want to
+                        * check idle time.
                         */
 
                        if (pool->ltp_state == LDAP_INT_THREAD_POOL_RUNNING
@@ -498,15 +489,6 @@ ldap_int_thread_pool_wrapper (
                        }
                        ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex);
                }
-               ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
-
-               ldap_pvt_thread_yield();
-
-               /* if we use an idle timer, here's
-                * a good place to update it
-                */
-
-               ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
        }
 
        for ( i=0; i<MAXKEYS && ltc_key[i].ltk_key; i++ ) {
@@ -520,6 +502,11 @@ ldap_int_thread_pool_wrapper (
        thread_keys[keyslot].id = tid_zero;
 
        pool->ltp_open_count--;
+
+       /* let pool_destroy know we're all done */
+       if (pool->ltp_open_count < 1)
+               ldap_pvt_thread_cond_signal(&pool->ltp_cond);
+
        ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
 
        ldap_pvt_thread_exit(NULL);
@@ -661,12 +648,14 @@ void *ldap_pvt_thread_pool_context( )
        int i, hash;
 
        tid = ldap_pvt_thread_self();
-       if ( TID_EQ( tid, ldap_int_main_tid ))
+       if ( ldap_pvt_thread_equal( tid, ldap_int_main_tid ))
                return ldap_int_main_thrctx;
 
        TID_HASH( tid, hash );
-       for (i = hash & (LDAP_MAXTHR-1); !TID_EQ(thread_keys[i].id, tid_zero) &&
-               !TID_EQ(thread_keys[i].id, tid); i = (i+1) & (LDAP_MAXTHR-1));
+       for (i = hash & (LDAP_MAXTHR-1);
+               !ldap_pvt_thread_equal(thread_keys[i].id, tid_zero) &&
+               !ldap_pvt_thread_equal(thread_keys[i].id, tid);
+               i = (i+1) & (LDAP_MAXTHR-1));
 
        return thread_keys[i].ctx;
 }