union {
LDAP_STAILQ_ENTRY(ldap_int_thread_ctx_s) q;
LDAP_SLIST_ENTRY(ldap_int_thread_ctx_s) l;
+ LDAP_SLIST_ENTRY(ldap_int_thread_ctx_s) al;
} 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[MAXKEYS];
} ldap_int_thread_ctx_t;
ldap_pvt_thread_cond_t ltp_cond;
LDAP_STAILQ_HEAD(tcq, ldap_int_thread_ctx_s) ltp_pending_list;
LDAP_SLIST_HEAD(tcl, ldap_int_thread_ctx_s) ltp_free_list;
+ LDAP_SLIST_HEAD(tclq, ldap_int_thread_ctx_s) ltp_active_list;
long ltp_state;
long ltp_max_count;
long ltp_max_pending;
pool->ltp_max_pending = max_pending;
LDAP_STAILQ_INIT(&pool->ltp_pending_list);
LDAP_SLIST_INIT(&pool->ltp_free_list);
+ LDAP_SLIST_INIT(&pool->ltp_active_list);
ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex);
LDAP_STAILQ_INSERT_TAIL(&ldap_int_thread_pool_list, pool, ltp_next);
ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex);
LDAP_FREE(ctx);
}
+ while ((ctx = LDAP_SLIST_FIRST(&pool->ltp_active_list)) != NULL)
+ {
+ LDAP_SLIST_REMOVE_HEAD(&pool->ltp_active_list, ltc_next.al);
+ }
+
ldap_pvt_thread_cond_destroy(&pool->ltp_cond);
ldap_pvt_thread_mutex_destroy(&pool->ltp_mutex);
LDAP_FREE(pool);
}
pool->ltp_pending_count--;
+ 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_thread_id = ldap_pvt_thread_self();
ctx->ltc_start_routine(ctx, ctx->ltc_arg);
ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
pool->ltp_active_count--;
+ ctx = LDAP_SLIST_FIRST(&pool->ltp_active_list);
+ if (ctx) {
+ LDAP_SLIST_REMOVE_HEAD(&pool->ltp_active_list, ltc_next.al);
+ }
}
pool->ltp_open_count--;
}
return ENOMEM;
}
+
+/*
+ * This is necessary if the caller does not have access to the
+ * thread context handle (for example, a slapd plugin calling
+ * slapi_search_internal()). No doubt it is more efficient to
+ * for the application to keep track of the thread context
+ * handles itself.
+ */
+void *ldap_pvt_thread_pool_context( ldap_pvt_thread_pool_t *tpool )
+{
+ ldap_pvt_thread_pool_t pool;
+ ldap_pvt_thread_t tid;
+ ldap_int_thread_ctx_t *ptr;
+
+ pool = *tpool;
+ if (pool == NULL) {
+ return NULL;
+ }
+
+ 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);
+
+ return ptr;
+}
+
#endif /* LDAP_HAVE_THREAD_POOL */