]> git.sur5r.net Git - openldap/commitdiff
Add ldap_pvt_thread_pool_retract() to cancel pending threads
authorHoward Chu <hyc@openldap.org>
Thu, 11 Jun 2009 04:46:04 +0000 (04:46 +0000)
committerHoward Chu <hyc@openldap.org>
Thu, 11 Jun 2009 04:46:04 +0000 (04:46 +0000)
include/ldap_pvt_thread.h
libraries/libldap_r/tpool.c
servers/slapd/syncrepl.c

index 738140fb2fbeb1929cd89956006eb5ccc2d81b54..bd928a771fcf0b7a1e265f9f0f9a378893a82a20 100644 (file)
@@ -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,
index 209a1ac800e8fc20a24b23f3b030b83ffa125aa2..7e841898f52d2a0b91cf01dcc2a126e03ea110ce 100644 (file)
@@ -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(
index 6b16e0470f9530c75a725cdabf1134b281d8d091..07e9dd78577fb08c33b472ac2a67a339204a7b06 100644 (file)
@@ -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 );
                                                }