* 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 {
} 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 {
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.
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;
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) {
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,
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);
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;
}
}
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;
}
}
* 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 */