]> git.sur5r.net Git - openldap/commitdiff
ITS#6413
authorQuanah Gibson-Mount <quanah@openldap.org>
Fri, 4 Dec 2009 19:40:23 +0000 (19:40 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Fri, 4 Dec 2009 19:40:23 +0000 (19:40 +0000)
CHANGES
servers/slapd/syncrepl.c

diff --git a/CHANGES b/CHANGES
index 5380475d8e484100a5c8745706990ae66e9e35a9..3f78f31456b743b81d99ea8509d39a66fb75c8eb 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,7 @@ OpenLDAP 2.4 Change Log
 
 OpenLDAP 2.4.21 Engineering
        Fixed liblutil for negative time offsets (ITS#6405)
+       Fixed slapd freeing tasks from queue (ITS#6413)
        Fixed slapd looping with SSL/TLS connections (ITS#6412)
        Fixed slapd use correct ce_type (ITS#6408)
        Fixed slapo-translucent with back-null (ITS#6403)
index fb1001f239943255b10defc829dc88914edaffc4..313fb93e38acf50517a19ee5e4947653e0a962ae 100644 (file)
@@ -4757,6 +4757,8 @@ syncrepl_config( ConfigArgs *c )
                                si = *sip;
                                if ( c->valx == -1 || i == c->valx ) {
                                        *sip = si->si_next;
+                                       si->si_ctype = -1;
+                                       si->si_next = NULL;
                                        /* If the task is currently active, we have to leave
                                         * it running. It will exit on its own. This will only
                                         * happen when running on the cn=config DB.
@@ -4765,22 +4767,34 @@ syncrepl_config( ConfigArgs *c )
                                                if ( ldap_pvt_thread_mutex_trylock( &si->si_mutex )) {
                                                        isrunning = 1;
                                                } else {
+                                                       /* There is no active thread, but we must still
+                                                        * ensure that no thread is (or will be) queued
+                                                        * while we removes the task.
+                                                        */
+                                                       struct re_s *re = si->si_re;
+                                                       si->si_re = NULL;
+
                                                        if ( si->si_conn ) {
-                                                               /* 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_pool_retract( &connection_pool,
-                                                                       si->si_re->routine, si->si_re );
+                                                               connection_client_stop( si->si_conn );
+                                                               si->si_conn = NULL;
+                                                       }
+
+                                                       ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
+                                                       if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) ) {
+                                                               ldap_pvt_runqueue_stoptask( &slapd_rq, re );
+                                                               isrunning = 1;
                                                        }
+                                                       ldap_pvt_runqueue_remove( &slapd_rq, re );
+                                                       ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
+
+                                                       if ( ldap_pvt_thread_pool_retract( &connection_pool,
+                                                                       re->routine, re ) > 0 )
+                                                               isrunning = 0;
+
                                                        ldap_pvt_thread_mutex_unlock( &si->si_mutex );
                                                }
                                        }
-                                       if ( isrunning ) {
-                                               si->si_ctype = -1;
-                                               si->si_next = NULL;
-                                       } else {
+                                       if ( !isrunning ) {
                                                syncinfo_free( si, 0 );
                                        }
                                        if ( i == c->valx )