Commit a6a6946a authored by Howard Chu's avatar Howard Chu
Browse files

New ldap_pvt_thread_pool_context()

parent a255dbb9
......@@ -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
......
......@@ -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 */
......@@ -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 */
......
......@@ -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;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment