]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap_r/tpool.c
Patch: ucdata 2.4 bugs (ITS#1751)
[openldap] / libraries / libldap_r / tpool.c
index 623328026bf9177fe0cd877339bad24deac8a698..923a1b9ce4e23c94e543c87b1e8fab17288e8744 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2002 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -20,7 +20,7 @@
 
 #include "ldap-int.h"
 #include "ldap_pvt_thread.h"
-#include "queue-compat.h"
+#include "ldap_queue.h"
 
 #ifndef LDAP_THREAD_HAVE_TPOOL
 
@@ -32,18 +32,19 @@ enum ldap_int_thread_pool_state {
 
 typedef struct ldap_int_thread_ctx_s {
        union {
-       SLIST_ENTRY(ldap_int_thread_ctx_s) l;
-       STAILQ_ENTRY(ldap_int_thread_ctx_s) q;
+       LDAP_STAILQ_ENTRY(ldap_int_thread_ctx_s) q;
+       LDAP_SLIST_ENTRY(ldap_int_thread_ctx_s) l;
        } ltc_next;
        void *(*ltc_start_routine)( void *);
        void *ltc_arg;
 } ldap_int_thread_ctx_t;
 
 struct ldap_int_thread_pool_s {
-       STAILQ_ENTRY(ldap_int_thread_pool_s) ltp_next;
+       LDAP_STAILQ_ENTRY(ldap_int_thread_pool_s) ltp_next;
        ldap_pvt_thread_mutex_t ltp_mutex;
        ldap_pvt_thread_cond_t ltp_cond;
-       STAILQ_HEAD(tcq, ldap_int_thread_ctx_s) ltp_pending_list;
+       LDAP_STAILQ_HEAD(tcq, ldap_int_thread_ctx_s) ltp_pending_list;
+       LDAP_SLIST_HEAD(tcl, ldap_int_thread_ctx_s) ltp_free_list;
        long ltp_state;
        long ltp_max_count;
        long ltp_max_pending;
@@ -53,44 +54,29 @@ struct ldap_int_thread_pool_s {
        long ltp_starting;
 };
 
-static STAILQ_HEAD(tpq, ldap_int_thread_pool_s)
+static LDAP_STAILQ_HEAD(tpq, ldap_int_thread_pool_s)
        ldap_int_thread_pool_list =
-       STAILQ_HEAD_INITIALIZER(ldap_int_thread_pool_list);
-
-static SLIST_HEAD(tcl, ldap_int_thread_ctx_s)
-       ldap_int_ctx_free_list = 
-       SLIST_HEAD_INITIALIZER(ldap_int_ctx_free_list);
+       LDAP_STAILQ_HEAD_INITIALIZER(ldap_int_thread_pool_list);
 
 static ldap_pvt_thread_mutex_t ldap_pvt_thread_pool_mutex;
-static ldap_pvt_thread_mutex_t ldap_pvt_ctx_free_mutex;
 
-static void *ldap_int_thread_pool_wrapper(
-       struct ldap_int_thread_pool_s *pool );
+static void *ldap_int_thread_pool_wrapper( void *pool );
 
 int
 ldap_int_thread_pool_startup ( void )
 {
-       int rc = ldap_pvt_thread_mutex_init(&ldap_pvt_thread_pool_mutex);
-       if (rc == 0)
-               rc = ldap_pvt_thread_mutex_init(&ldap_pvt_ctx_free_mutex);
-       return rc;
+       return ldap_pvt_thread_mutex_init(&ldap_pvt_thread_pool_mutex);
 }
 
 int
 ldap_int_thread_pool_shutdown ( void )
 {
-       ldap_int_thread_ctx_t *ctx;
        struct ldap_int_thread_pool_s *pool;
 
-       while ((pool = STAILQ_FIRST(&ldap_int_thread_pool_list)) != NULL) {
-               STAILQ_REMOVE_HEAD(&ldap_int_thread_pool_list, ltp_next);
+       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);
        }
-       while ((ctx = SLIST_FIRST(&ldap_int_ctx_free_list))) {
-               SLIST_REMOVE_HEAD(&ldap_int_ctx_free_list, ltc_next.l);
-               free(ctx);
-       }
-       ldap_pvt_thread_mutex_destroy(&ldap_pvt_ctx_free_mutex);
        ldap_pvt_thread_mutex_destroy(&ldap_pvt_thread_pool_mutex);
        return(0);
 }
@@ -119,9 +105,10 @@ ldap_pvt_thread_pool_init (
        pool->ltp_state = LDAP_INT_THREAD_POOL_RUNNING;
        pool->ltp_max_count = max_threads;
        pool->ltp_max_pending = max_pending;
-       STAILQ_INIT(&pool->ltp_pending_list);
+       LDAP_STAILQ_INIT(&pool->ltp_pending_list);
+       LDAP_SLIST_INIT(&pool->ltp_free_list);
        ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex);
-       STAILQ_INSERT_TAIL(&ldap_int_thread_pool_list, pool, ltp_next);
+       LDAP_STAILQ_INSERT_TAIL(&ldap_int_thread_pool_list, pool, ltp_next);
        ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex);
 
 #if 0
@@ -142,18 +129,17 @@ ldap_pvt_thread_pool_init (
        pool->ltp_open_count++;
 
        ldap_pvt_thread_t thr;
-       rc = ldap_pvt_thread_create( &thr, 1,
-               (void *) ldap_int_thread_pool_wrapper, pool );
+       rc = ldap_pvt_thread_create( &thr, 1, ldap_int_thread_pool_wrapper, pool );
 
        if( rc != 0) {
                /* couldn't start one?  then don't start any */
                ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex);
-               STAILQ_REMOVE(ldap_int_thread_pool_list, pool, 
-                       ldap_int_thread_element_s, ltp_next);
+               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_cond);
                ldap_pvt_thread_mutex_destroy(&pool->ltp_mutex);
-               free(pool);
+               LDAP_FREE(pool);
                return(-1);
        }
 #endif
@@ -188,13 +174,10 @@ ldap_pvt_thread_pool_submit (
                ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
                return(-1);
        }
-       ldap_pvt_thread_mutex_lock(&ldap_pvt_ctx_free_mutex);
-       ctx = SLIST_FIRST(&ldap_int_ctx_free_list);
+       ctx = LDAP_SLIST_FIRST(&pool->ltp_free_list);
        if (ctx) {
-               SLIST_REMOVE_HEAD(&ldap_int_ctx_free_list, ltc_next.l);
-               ldap_pvt_thread_mutex_unlock(&ldap_pvt_ctx_free_mutex);
+               LDAP_SLIST_REMOVE_HEAD(&pool->ltp_free_list, ltc_next.l);
        } else {
-               ldap_pvt_thread_mutex_unlock(&ldap_pvt_ctx_free_mutex);
                ctx = (ldap_int_thread_ctx_t *) LDAP_MALLOC(
                        sizeof(ldap_int_thread_ctx_t));
                if (ctx == NULL) {
@@ -207,7 +190,7 @@ ldap_pvt_thread_pool_submit (
        ctx->ltc_arg = arg;
 
        pool->ltp_pending_count++;
-       STAILQ_INSERT_TAIL(&pool->ltp_pending_list, ctx, ltc_next.q);
+       LDAP_STAILQ_INSERT_TAIL(&pool->ltp_pending_list, ctx, ltc_next.q);
        ldap_pvt_thread_cond_signal(&pool->ltp_cond);
        if ((pool->ltp_open_count <= 0
                        || pool->ltp_pending_count > 1
@@ -223,7 +206,7 @@ ldap_pvt_thread_pool_submit (
 
        if (need_thread) {
                int rc = ldap_pvt_thread_create( &thr, 1,
-                       (void *)ldap_int_thread_pool_wrapper, pool );
+                       ldap_int_thread_pool_wrapper, pool );
                ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
                if (rc == 0) {
                        pool->ltp_starting--;
@@ -237,18 +220,18 @@ ldap_pvt_thread_pool_submit (
                                /* no open threads at all?!?
                                 */
                                ldap_int_thread_ctx_t *ptr;
-                               STAILQ_FOREACH(ptr, &pool->ltp_pending_list, ltc_next.q)
+                               LDAP_STAILQ_FOREACH(ptr, &pool->ltp_pending_list, ltc_next.q)
                                        if (ptr == ctx) break;
                                if (ptr == ctx) {
                                        /* no open threads, context not handled, so
                                         * back out of ltp_pending_count, free the context,
                                         * report the error.
                                         */
-                                       STAILQ_REMOVE(&pool->ltp_pending_list, ctx, 
+                                       LDAP_STAILQ_REMOVE(&pool->ltp_pending_list, ctx, 
                                                ldap_int_thread_ctx_s, ltc_next.q);
                                        pool->ltp_pending_count++;
                                        ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
-                                       free(ctx);
+                                       LDAP_FREE(ctx);
                                        return(-1);
                                }
                        }
@@ -318,10 +301,10 @@ ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t *tpool, int run_pending )
        if (pool == NULL) return(-1);
 
        ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex);
-       STAILQ_FOREACH(pptr, &ldap_int_thread_pool_list, ltp_next)
+       LDAP_STAILQ_FOREACH(pptr, &ldap_int_thread_pool_list, ltp_next)
                if (pptr == pool) break;
        if (pptr == pool)
-               STAILQ_REMOVE(&ldap_int_thread_pool_list, 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);
 
@@ -348,22 +331,29 @@ ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t *tpool, int run_pending )
                ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
        } while (waiting > 0);
 
-       while ((ctx = STAILQ_FIRST(&pool->ltp_pending_list)) != NULL)
+       while ((ctx = LDAP_STAILQ_FIRST(&pool->ltp_pending_list)) != NULL)
+       {
+               LDAP_STAILQ_REMOVE_HEAD(&pool->ltp_pending_list, ltc_next.q);
+               LDAP_FREE(ctx);
+       }
+
+       while ((ctx = LDAP_SLIST_FIRST(&pool->ltp_free_list)) != NULL)
        {
-               STAILQ_REMOVE_HEAD(&pool->ltp_pending_list, ltc_next.q);
-               free(ctx);
+               LDAP_SLIST_REMOVE_HEAD(&pool->ltp_free_list, ltc_next.l);
+               LDAP_FREE(ctx);
        }
 
        ldap_pvt_thread_cond_destroy(&pool->ltp_cond);
        ldap_pvt_thread_mutex_destroy(&pool->ltp_mutex);
-       free(pool);
+       LDAP_FREE(pool);
        return(0);
 }
 
 static void *
 ldap_int_thread_pool_wrapper ( 
-       struct ldap_int_thread_pool_s *pool )
+       void *xpool )
 {
+       struct ldap_int_thread_pool_s *pool = xpool;
        ldap_int_thread_ctx_t *ctx;
 
        if (pool == NULL)
@@ -372,9 +362,9 @@ ldap_int_thread_pool_wrapper (
        ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
 
        while (pool->ltp_state != LDAP_INT_THREAD_POOL_STOPPING) {
-               ctx = STAILQ_FIRST(&pool->ltp_pending_list);
+               ctx = LDAP_STAILQ_FIRST(&pool->ltp_pending_list);
                if (ctx) {
-                       STAILQ_REMOVE_HEAD(&pool->ltp_pending_list, ltc_next.q);
+                       LDAP_STAILQ_REMOVE_HEAD(&pool->ltp_pending_list, ltc_next.q);
                } else {
                        if (pool->ltp_state == LDAP_INT_THREAD_POOL_FINISHING)
                                break;
@@ -409,9 +399,7 @@ ldap_int_thread_pool_wrapper (
                ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
 
                (ctx->ltc_start_routine)(ctx->ltc_arg);
-               ldap_pvt_thread_mutex_lock(&ldap_pvt_ctx_free_mutex);
-               SLIST_INSERT_HEAD(&ldap_int_ctx_free_list, ctx, ltc_next.l);
-               ldap_pvt_thread_mutex_unlock(&ldap_pvt_ctx_free_mutex);
+               LDAP_SLIST_INSERT_HEAD(&pool->ltp_free_list, ctx, ltc_next.l);
                ldap_pvt_thread_yield();
 
                /* if we use an idle timer, here's