]> git.sur5r.net Git - openldap/commitdiff
New ldap_pvt_thread_pool_context()
authorHoward Chu <hyc@openldap.org>
Sat, 12 Apr 2003 04:01:40 +0000 (04:01 +0000)
committerHoward Chu <hyc@openldap.org>
Sat, 12 Apr 2003 04:01:40 +0000 (04:01 +0000)
include/ldap_pvt_thread.h
libraries/libldap_r/tpool.c
servers/slapd/back-bdb/cache.c
servers/slapd/slapi/slapi_ops.c

index d02359ad9e4eb49bfae70b73bb1a5425cc68f638..ca4a2c5585c75602fada927d17554f2b419f986a 100644 (file)
@@ -188,8 +188,7 @@ ldap_pvt_thread_pool_setkey LDAP_P((
        ldap_pvt_thread_pool_keyfree_t *kfree ));
 
 LDAP_F( void *)
-ldap_pvt_thread_pool_context LDAP_P((
-       ldap_pvt_thread_pool_t *pool ));
+ldap_pvt_thread_pool_context LDAP_P(( void ));
 
 LDAP_END_DECL
 
index f9ecded4d588aabf6ad07f94eafc9e4bc98cd54f..c6eeed959cf85b1c8c823e4741c0ce944bb4668c 100644 (file)
@@ -41,6 +41,13 @@ typedef struct ldap_int_thread_key_s {
  * We don't expect to use many...
  */
 #define        MAXKEYS 32
+#define        MAXTHREADS      1024    /* must be a power of 2 */
+
+static struct {
+       ldap_pvt_thread_t id;
+       ldap_int_thread_key_t *ctx;
+} thread_keys[MAXTHREADS];
+       
 
 typedef struct ldap_int_thread_ctx_s {
        union {
@@ -50,8 +57,6 @@ typedef struct ldap_int_thread_ctx_s {
        } ltc_next;
        ldap_pvt_thread_start_t *ltc_start_routine;
        void *ltc_arg;
-       ldap_pvt_thread_t ltc_thread_id;
-       ldap_int_thread_key_t *ltc_key;
 } ldap_int_thread_ctx_t;
 
 struct ldap_int_thread_pool_s {
@@ -225,11 +230,22 @@ ldap_pvt_thread_pool_submit (
        ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
 
        if (need_thread) {
-               int rc = ldap_pvt_thread_create( &thr, 1,
-                       ldap_int_thread_pool_wrapper, pool );
+               int rc;
+
                ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
+
+               rc = ldap_pvt_thread_create( &thr, 1,
+                       ldap_int_thread_pool_wrapper, pool );
                if (rc == 0) {
                        pool->ltp_starting--;
+
+                       /* assign this thread ID to a key slot; start
+                        * at the thread ID itself (mod MAXTHREADS) and
+                        * look for an empty slot.
+                        */
+                       for (rc = thr & (MAXTHREADS-1); thread_keys[rc].id;
+                               rc = (rc+1) & (MAXTHREADS-1));
+                       thread_keys[rc].id = thr;
                } else {
                        /* couldn't create thread.  back out of
                         * ltp_open_count and check for even worse things.
@@ -370,7 +386,8 @@ ldap_int_thread_pool_wrapper (
        struct ldap_int_thread_pool_s *pool = xpool;
        ldap_int_thread_ctx_t *ctx;
        ldap_int_thread_key_t ltc_key[MAXKEYS];
-       int i;
+       ldap_pvt_thread_t tid;
+       int i, keyslot;
 
        if (pool == NULL)
                return NULL;
@@ -379,8 +396,16 @@ ldap_int_thread_pool_wrapper (
                ltc_key[i].ltk_key = NULL;
        }
 
+       tid = ldap_pvt_thread_self();
+
        ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
 
+       /* store pointer to our keys */
+       for (i = tid & (MAXTHREADS-1); thread_keys[i].id != tid;
+                               i = (i+1) & (MAXTHREADS-1));
+       thread_keys[i].ctx = ltc_key;
+       keyslot = i;
+
        while (pool->ltp_state != LDAP_INT_THREAD_POOL_STOPPING) {
                ctx = LDAP_STAILQ_FIRST(&pool->ltp_pending_list);
                if (ctx) {
@@ -416,15 +441,11 @@ ldap_int_thread_pool_wrapper (
 
                pool->ltp_pending_count--;
 
-               ctx->ltc_key = ltc_key;
-               ctx->ltc_thread_id = ldap_pvt_thread_self();
-
                LDAP_SLIST_INSERT_HEAD(&pool->ltp_active_list, ctx, ltc_next.al);
                pool->ltp_active_count++;
                ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
 
-               ctx->ltc_start_routine(ctx, ctx->ltc_arg);
-               ctx->ltc_key = NULL;
+               ctx->ltc_start_routine(ltc_key, ctx->ltc_arg);
 
                ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
                LDAP_SLIST_REMOVE(&pool->ltp_active_list, ctx,
@@ -449,6 +470,9 @@ ldap_int_thread_pool_wrapper (
                                ltc_key[i].ltk_data );
        }
 
+       thread_keys[keyslot].ctx = NULL;
+       thread_keys[keyslot].id = 0;
+
        pool->ltp_open_count--;
        ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
 
@@ -462,15 +486,15 @@ int ldap_pvt_thread_pool_getkey(
        void **data,
        ldap_pvt_thread_pool_keyfree_t **kfree )
 {
-       ldap_int_thread_ctx_t *ctx = xctx;
+       ldap_int_thread_key_t *ctx = xctx;
        int i;
 
-       if ( !ctx || !data || !ctx->ltc_key ) return EINVAL;
+       if ( !ctx || !data ) return EINVAL;
 
-       for ( i=0; i<MAXKEYS && ctx->ltc_key[i].ltk_key; i++ ) {
-               if ( ctx->ltc_key[i].ltk_key == key ) {
-                       *data = ctx->ltc_key[i].ltk_data;
-                       if ( kfree ) *kfree = ctx->ltc_key[i].ltk_free;
+       for ( i=0; i<MAXKEYS && ctx[i].ltk_key; i++ ) {
+               if ( ctx[i].ltk_key == key ) {
+                       *data = ctx[i].ltk_data;
+                       if ( kfree ) *kfree = ctx[i].ltk_free;
                        return 0;
                }
        }
@@ -483,16 +507,16 @@ int ldap_pvt_thread_pool_setkey(
        void *data,
        ldap_pvt_thread_pool_keyfree_t *kfree )
 {
-       ldap_int_thread_ctx_t *ctx = xctx;
+       ldap_int_thread_key_t *ctx = xctx;
        int i;
 
-       if ( !ctx || !key || !ctx->ltc_key ) return EINVAL;
+       if ( !ctx || !key ) return EINVAL;
 
        for ( i=0; i<MAXKEYS; i++ ) {
-               if ( !ctx->ltc_key[i].ltk_key || ctx->ltc_key[i].ltk_key == key ) {
-                       ctx->ltc_key[i].ltk_key = key;
-                       ctx->ltc_key[i].ltk_data = data;
-                       ctx->ltc_key[i].ltk_free = kfree;
+               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;
                        return 0;
                }
        }
@@ -506,28 +530,17 @@ int ldap_pvt_thread_pool_setkey(
  * for the application to keep track of the thread context
  * handles itself.
  */
-void *ldap_pvt_thread_pool_context( ldap_pvt_thread_pool_t *tpool )
+void *ldap_pvt_thread_pool_context( )
 {
-       ldap_pvt_thread_pool_t pool;
        ldap_pvt_thread_t tid;
-       ldap_int_thread_ctx_t *ptr;
-
-       pool = *tpool;
-       if (pool == NULL) {
-               return NULL;
-       }
+       int i;
 
        tid = ldap_pvt_thread_self();
 
-       ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
-       LDAP_SLIST_FOREACH(ptr, &pool->ltp_active_list, ltc_next.al)
-               if (ptr != NULL && ptr->ltc_thread_id == tid) break;
-       if (ptr != NULL && ptr->ltc_thread_id != tid) {
-               ptr = NULL;
-       }
-       ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
+       for (i = tid & (MAXTHREADS-1); thread_keys[i].id &&
+               thread_keys[i].id != tid; i = (i+1) & (MAXTHREADS-1));
 
-       return ptr;
+       return thread_keys[i].ctx;
 }
 
 #endif /* LDAP_HAVE_THREAD_POOL */
index 7bbabf84571a75545cdcc0e7081bfdba481bf8a4..eec734a565514569a3ca9db3513d7c561af502ee 100644 (file)
@@ -1151,7 +1151,7 @@ bdb_locker_id( Operation *op, DB_ENV *env, int *locker )
        if ( op ) {
                ctx = op->o_threadctx;
        } else {
-               ctx = ldap_pvt_thread_pool_context( &connection_pool );
+               ctx = ldap_pvt_thread_pool_context();
        }
 
        /* Shouldn't happen unless we're single-threaded */
index bc1e84cea8b759fad9123c45bf1f18f3334e1a99..0cc32804d445c99a8ff228f941191df532b04e82 100644 (file)
@@ -156,7 +156,7 @@ slapiConnectionInit(
        c->c_pending_ops.stqh_first->o_authmech.bv_len = 0; 
        c->c_pending_ops.stqh_first->o_time = slap_get_time();
        c->c_pending_ops.stqh_first->o_do_not_cache = 1;
-       c->c_pending_ops.stqh_first->o_threadctx = ldap_pvt_thread_pool_context( &connection_pool );
+       c->c_pending_ops.stqh_first->o_threadctx = ldap_pvt_thread_pool_context();
        c->c_pending_ops.stqh_first->o_tmpmemctx = NULL;
        c->c_pending_ops.stqh_first->o_tmpmfuncs = &ch_mfuncs;
        c->c_pending_ops.stqh_first->o_conn = c;