From: Howard Chu Date: Thu, 11 Jun 2009 04:46:04 +0000 (+0000) Subject: Add ldap_pvt_thread_pool_retract() to cancel pending threads X-Git-Tag: ACLCHECK_0~503 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=23783a9164b525b4c134ec6ede8c6159d9b7eb50;p=openldap Add ldap_pvt_thread_pool_retract() to cancel pending threads --- diff --git a/include/ldap_pvt_thread.h b/include/ldap_pvt_thread.h index 738140fb2f..bd928a771f 100644 --- a/include/ldap_pvt_thread.h +++ b/include/ldap_pvt_thread.h @@ -215,6 +215,12 @@ ldap_pvt_thread_pool_submit LDAP_P(( ldap_pvt_thread_start_t *start, void *arg )); +LDAP_F( int ) +ldap_pvt_thread_pool_retract LDAP_P(( + ldap_pvt_thread_pool_t *pool, + ldap_pvt_thread_start_t *start, + void *arg )); + LDAP_F( int ) ldap_pvt_thread_pool_maxthreads LDAP_P(( ldap_pvt_thread_pool_t *pool, diff --git a/libraries/libldap_r/tpool.c b/libraries/libldap_r/tpool.c index 209a1ac800..7e841898f5 100644 --- a/libraries/libldap_r/tpool.c +++ b/libraries/libldap_r/tpool.c @@ -373,6 +373,40 @@ ldap_pvt_thread_pool_submit ( return(-1); } +/* Cancel a pending thread that was previously submitted. + * Return 1 if the thread was successfully cancelled, 0 if + * not found, -1 for invalid parameters + */ +int +ldap_pvt_thread_pool_retract ( + ldap_pvt_thread_pool_t *tpool, + ldap_pvt_thread_start_t *start_routine, void *arg ) +{ + struct ldap_int_thread_pool_s *pool; + ldap_int_thread_task_t *task; + + if (tpool == NULL) + return(-1); + + pool = *tpool; + + if (pool == NULL) + return(-1); + + ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); + LDAP_STAILQ_FOREACH(task, &pool->ltp_pending_list, ltt_next.q) + if (task->ltt_start_routine == start_routine && + task->ltt_arg == arg) { + pool->ltp_pending_count--; + LDAP_STAILQ_REMOVE(&pool->ltp_pending_list, task, + ldap_int_thread_task_s, ltt_next.q); + LDAP_SLIST_INSERT_HEAD(&pool->ltp_free_list, task, + ltt_next.l); + return 1; + } + return 0; +} + /* Set max #threads. value <= 0 means max supported #threads (LDAP_MAXTHR) */ int ldap_pvt_thread_pool_maxthreads( diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 6b16e0470f..07e9dd7857 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -4631,21 +4631,13 @@ syncrepl_config( ConfigArgs *c ) isrunning = 1; } else { if ( si->si_conn ) { - isrunning = 1; - /* If there's a persistent connection, we don't - * know if it's already got a thread queued. - * so defer the free, but reschedule the task. - * If there's a connection thread queued, it - * will cleanup as necessary. If not, then the - * runqueue task will cleanup. + /* If there's a persistent connection, it may + * already have a thread queued. We know it's + * not active, so it must be pending and we + * can simply cancel it now. */ - ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); - if ( !ldap_pvt_runqueue_isrunning( &slapd_rq, si->si_re )) { - si->si_re->interval.tv_sec = 0; - ldap_pvt_runqueue_resched( &slapd_rq, si->si_re, 0 ); - si->si_re->interval.tv_sec = si->si_interval; - } - ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); + ldap_pvt_thread_pool_retract( &connection_pool, + si->si_re->routine, si->si_re ); } ldap_pvt_thread_mutex_unlock( &si->si_mutex ); }