From: Howard Chu Date: Sat, 24 Aug 2002 05:39:43 +0000 (+0000) Subject: Added thread-pool getkey/setkey functions X-Git-Tag: NO_SLAP_OP_BLOCKS~1189 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=8c30114d847ff034dd9e9382d88e276fa7f82833;p=openldap Added thread-pool getkey/setkey functions --- diff --git a/include/ldap_pvt_thread.h b/include/ldap_pvt_thread.h index 3179f138c2..4989cb4b73 100644 --- a/include/ldap_pvt_thread.h +++ b/include/ldap_pvt_thread.h @@ -141,6 +141,9 @@ ldap_pvt_thread_rdwr_active LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp)); typedef ldap_int_thread_pool_t ldap_pvt_thread_pool_t; +typedef void * (ldap_pvt_thread_start_t) LDAP_P((void *ctx, void *arg)); +typedef void (ldap_pvt_thread_pool_keyfree_t) LDAP_P((void *key, void *data)); + LDAP_F( int ) ldap_pvt_thread_pool_init LDAP_P(( ldap_pvt_thread_pool_t *pool_out, @@ -150,7 +153,7 @@ ldap_pvt_thread_pool_init LDAP_P(( LDAP_F( int ) ldap_pvt_thread_pool_submit LDAP_P(( ldap_pvt_thread_pool_t *pool, - void *(*start_routine)( void * ), + ldap_pvt_thread_start_t *start, void *arg )); LDAP_F( int ) @@ -167,6 +170,20 @@ ldap_pvt_thread_pool_destroy LDAP_P(( ldap_pvt_thread_pool_t *pool, int run_pending )); +LDAP_F( int ) +ldap_pvt_thread_pool_getkey LDAP_P(( + void *ctx, + void *key, + void **data, + ldap_pvt_thread_pool_keyfree_t **kfree )); + +LDAP_F( int ) +ldap_pvt_thread_pool_setkey LDAP_P(( + void *ctx, + void *key, + void *data, + ldap_pvt_thread_pool_keyfree_t *kfree )); + LDAP_END_DECL diff --git a/libraries/libldap_r/thr_stub.c b/libraries/libldap_r/thr_stub.c index eacdd5ea44..28e3e32670 100644 --- a/libraries/libldap_r/thr_stub.c +++ b/libraries/libldap_r/thr_stub.c @@ -154,9 +154,9 @@ ldap_pvt_thread_pool_init ( int ldap_pvt_thread_pool_submit ( ldap_pvt_thread_pool_t *pool, - void *(*start_routine)( void * ), void *arg ) + ldap_pvt_thread_start_t *start_routine, void *arg ) { - (start_routine)(arg); + (start_routine)(NULL, arg); return(0); } @@ -180,4 +180,15 @@ ldap_pvt_thread_pool_destroy ( return(0); } +int ldap_pvt_thread_pool_getkey ( + void *ctx, void *key, void **data, void **kfree ) +{ + return(0); +} + +int ldap_pvt_thread_pool_setkey ( + void *ctx, void *key, void *data, void *kfree ) +{ + return(0); +} #endif /* NO_THREADS */ diff --git a/libraries/libldap_r/tpool.c b/libraries/libldap_r/tpool.c index d48a8e9370..4665f35a51 100644 --- a/libraries/libldap_r/tpool.c +++ b/libraries/libldap_r/tpool.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "ldap-int.h" #include "ldap_pvt_thread.h" @@ -30,13 +31,25 @@ enum ldap_int_thread_pool_state { LDAP_INT_THREAD_POOL_STOPPING }; +typedef struct ldap_int_thread_key_s { + void *ltk_key; + void *ltk_data; + ldap_pvt_thread_pool_keyfree_t *ltk_free; +} ldap_int_thread_key_t; + +/* Max number of thread-specific keys we store per thread. + * We don't expect to use many... + */ +#define MAXKEYS 32 + typedef struct ldap_int_thread_ctx_s { union { 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 *); + ldap_pvt_thread_start_t *ltc_start_routine; void *ltc_arg; + ldap_int_thread_key_t ltc_key[MAXKEYS]; } ldap_int_thread_ctx_t; struct ldap_int_thread_pool_s { @@ -151,7 +164,7 @@ ldap_pvt_thread_pool_init ( int ldap_pvt_thread_pool_submit ( ldap_pvt_thread_pool_t *tpool, - void *(*start_routine)( void * ), void *arg ) + ldap_pvt_thread_start_t *start_routine, void *arg ) { struct ldap_int_thread_pool_s *pool; ldap_int_thread_ctx_t *ctx; @@ -178,12 +191,16 @@ ldap_pvt_thread_pool_submit ( if (ctx) { LDAP_SLIST_REMOVE_HEAD(&pool->ltp_free_list, ltc_next.l); } else { + int i; ctx = (ldap_int_thread_ctx_t *) LDAP_MALLOC( sizeof(ldap_int_thread_ctx_t)); if (ctx == NULL) { ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); return(-1); } + for ( i=0; iltc_key[i].ltk_key = NULL; + } } ctx->ltc_start_routine = start_routine; @@ -286,6 +303,17 @@ ldap_pvt_thread_pool_backload ( ldap_pvt_thread_pool_t *tpool ) return(count); } +static void ldap_int_thread_pool_keyfree( ldap_int_thread_ctx_t *ctx ) +{ + int i; + for ( i=0; iltc_key[i].ltk_key; i++ ) { + if (ctx->ltc_key[i].ltk_free) + ctx->ltc_key[i].ltk_free( + ctx->ltc_key[i].ltk_key, + ctx->ltc_key[i].ltk_data ); + } +} + int ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t *tpool, int run_pending ) { @@ -334,12 +362,14 @@ ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t *tpool, int run_pending ) while ((ctx = LDAP_STAILQ_FIRST(&pool->ltp_pending_list)) != NULL) { LDAP_STAILQ_REMOVE_HEAD(&pool->ltp_pending_list, ltc_next.q); + ldap_int_thread_pool_keyfree( ctx ); LDAP_FREE(ctx); } while ((ctx = LDAP_SLIST_FIRST(&pool->ltp_free_list)) != NULL) { LDAP_SLIST_REMOVE_HEAD(&pool->ltp_free_list, ltc_next.l); + ldap_int_thread_pool_keyfree( ctx ); LDAP_FREE(ctx); } @@ -398,7 +428,7 @@ ldap_int_thread_pool_wrapper ( pool->ltp_active_count++; ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); - (ctx->ltc_start_routine)(ctx->ltc_arg); + ctx->ltc_start_routine(ctx, ctx->ltc_arg); ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); LDAP_SLIST_INSERT_HEAD(&pool->ltp_free_list, ctx, ltc_next.l); @@ -417,7 +447,51 @@ ldap_int_thread_pool_wrapper ( pool->ltp_open_count--; ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); + ldap_pvt_thread_exit(NULL); return(NULL); } + +int ldap_pvt_thread_pool_getkey( + void *xctx, + void *key, + void **data, + ldap_pvt_thread_pool_keyfree_t **kfree ) +{ + ldap_int_thread_ctx_t *ctx = xctx; + int i; + + if ( !ctx || !data ) return EINVAL; + + for ( i=0; iltc_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; + return 0; + } + } + return ENOENT; +} + +int ldap_pvt_thread_pool_setkey( + void *xctx, + void *key, + void *data, + ldap_pvt_thread_pool_keyfree_t *kfree ) +{ + ldap_int_thread_ctx_t *ctx = xctx; + int i; + + if ( !ctx || !key ) return EINVAL; + + for ( i=0; iltc_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; + return 0; + } + } + return ENOMEM; +} #endif /* LDAP_HAVE_THREAD_POOL */ diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index 8570a4a163..7e99f261b2 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -60,6 +60,8 @@ static int connection_resched( Connection *conn ); static void connection_abandon( Connection *conn ); static void connection_destroy( Connection *c ); +static ldap_pvt_thread_start_t connection_operation; + struct co_arg { Connection *co_conn; Operation *co_op; @@ -904,7 +906,7 @@ void connection_done( Connection *c ) #endif /* !SLAPD_MONITOR */ static void * -connection_operation( void *arg_v ) +connection_operation( void *ctx, void *arg_v ) { int rc; struct co_arg *arg = arg_v; @@ -918,6 +920,8 @@ connection_operation( void *arg_v ) num_ops_initiated++; ldap_pvt_thread_mutex_unlock( &num_ops_mutex ); + arg->co_op->o_threadctx = ctx; + if( conn->c_sasl_bind_in_progress && tag != LDAP_REQ_BIND ) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, ERR, diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 8ad39c3272..94f95bf11c 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1542,6 +1542,7 @@ typedef struct slap_op { slap_callback *o_callback; /* callback pointers */ LDAPControl **o_ctrls; /* controls */ + void *o_threadctx; /* thread pool thread context */ void *o_private; /* anything the backend needs */ LDAP_STAILQ_ENTRY(slap_op) o_next; /* next operation in list */