]> git.sur5r.net Git - openldap/commitdiff
ITS#6335 Don't reuse a modtarget someone is about to remove
authorRein Tollevik <rein@openldap.org>
Fri, 16 Oct 2009 17:27:18 +0000 (17:27 +0000)
committerRein Tollevik <rein@openldap.org>
Fri, 16 Oct 2009 17:27:18 +0000 (17:27 +0000)
servers/slapd/overlays/syncprov.c

index b9920698b6713da92a4255375d998da7571709f2..85b0b8cd8137c4404f9ff449c54d0562d30a74a1 100644 (file)
@@ -1324,15 +1324,14 @@ syncprov_op_cleanup( Operation *op, SlapReply *rs )
        /* Remove op from lock table */
        mt = opc->smt;
        if ( mt ) {
-               modinst *mi = mt->mt_mods;
-
+               ldap_pvt_thread_mutex_lock( &mt->mt_mutex );
+               mt->mt_mods = mt->mt_mods->mi_next;
                /* If there are more, promote the next one */
-               if ( mi->mi_next ) {
-                       ldap_pvt_thread_mutex_lock( &mt->mt_mutex );
-                       mt->mt_mods = mi->mi_next;
+               if ( mt->mt_mods ) {
                        mt->mt_op = mt->mt_mods->mi_op;
                        ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );
                } else {
+                       ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );
                        ldap_pvt_thread_mutex_lock( &si->si_mods_mutex );
                        avl_delete( &si->si_mods, mt, sp_avl_cmp );
                        ldap_pvt_thread_mutex_unlock( &si->si_mods_mutex );
@@ -1946,6 +1945,15 @@ syncprov_op_mod( Operation *op, SlapReply *rs )
                mt = avl_find( si->si_mods, &mtdummy, sp_avl_cmp );
                if ( mt ) {
                        ldap_pvt_thread_mutex_lock( &mt->mt_mutex );
+                       if ( mt->mt_mods == NULL ) {
+                               /* Cannot reuse this mt, as another thread is about
+                                * to release it in syncprov_op_cleanup.
+                                */
+                               ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );
+                               mt = NULL;
+                       }
+               }
+               if ( mt ) {
                        ldap_pvt_thread_mutex_unlock( &si->si_mods_mutex );
                        mt->mt_tail->mi_next = mi;
                        mt->mt_tail = mi;