]> git.sur5r.net Git - openldap/commitdiff
ITS#6709
authorQuanah Gibson-Mount <quanah@openldap.org>
Sun, 12 Dec 2010 05:11:53 +0000 (05:11 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Sun, 12 Dec 2010 05:11:53 +0000 (05:11 +0000)
CHANGES
servers/slapd/overlays/syncprov.c

diff --git a/CHANGES b/CHANGES
index c3e80b16e0cb99f545aaa421a91cd9f866508a71..10b114ec2ccc4a24f6d6f6391680105887ec57f4 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -24,6 +24,7 @@ OpenLDAP 2.4.24 Engineering
        Fixed slapo-sssvlv initialization (ITS#6649)
        Fixed slapo-syncprov to send error if consumer is newer (ITS#6606)
        Fixed slapo-syncprov properly mutex filter (ITS#6708)
+       Fixed slapo-syncprov active mod race (ITS#6709)
        Fixed contrib/nssov to only close socket on shutdown (ITS#6676)
        Documentation
                admin24 guide typo fixes (ITS#6609)
index c708dc6db64c0161deee7cb3d2b16a29e1fdae81..49a4af766adfb2ce3a1ed8c5510cef28aeac3b30 100644 (file)
@@ -133,6 +133,7 @@ typedef struct syncprov_info_t {
        int             si_numops;      /* number of ops since last checkpoint */
        int             si_nopres;      /* Skip present phase */
        int             si_usehint;     /* use reload hint */
+       int             si_active;      /* True if there are active mods */
        time_t  si_chklast;     /* time of last checkpoint */
        Avlnode *si_mods;       /* entries being modified */
        sessionlog      *si_logs;
@@ -1376,6 +1377,11 @@ syncprov_op_cleanup( Operation *op, SlapReply *rs )
        syncmatches *sm, *snext;
        modtarget *mt, mtdummy;
 
+       ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
+       if ( si->si_active )
+               si->si_active--;
+       ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
+
        for (sm = opc->smatches; sm; sm=snext) {
                snext = sm->sm_next;
                syncprov_free_syncop( sm->sm_op );
@@ -1976,6 +1982,7 @@ syncprov_op_mod( Operation *op, SlapReply *rs )
 
        ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
        have_psearches = ( si->si_ops != NULL );
+       si->si_active++;
        ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
 
        cbsize = sizeof(slap_callback) + sizeof(opcookie) +
@@ -2410,6 +2417,20 @@ syncprov_op_search( Operation *op, SlapReply *rs )
                sop->s_inuse = 1;
 
                ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
+               while ( si->si_active ) {
+                       /* Wait for active mods to finish before proceeding, as they
+                        * may already have inspected the si_ops list looking for
+                        * consumers to replicate the change to.  Using the log
+                        * doesn't help, as we may finish playing it before the
+                        * active mods gets added to it.
+                        */
+                       ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
+                       if ( slapd_shutdown )
+                               return SLAPD_ABANDON;
+                       if ( !ldap_pvt_thread_pool_pausecheck( &connection_pool ))
+                               ldap_pvt_thread_yield();
+                       ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
+               }
                sop->s_next = si->si_ops;
                si->si_ops = sop;
                ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );