]> git.sur5r.net Git - openldap/commitdiff
ITS#6335
authorQuanah Gibson-Mount <quanah@openldap.org>
Fri, 30 Oct 2009 19:19:12 +0000 (19:19 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Fri, 30 Oct 2009 19:19:12 +0000 (19:19 +0000)
CHANGES
servers/slapd/overlays/syncprov.c

diff --git a/CHANGES b/CHANGES
index 2f9cbe3ed82e1df43c119849ce9857769d85eb1c..af333bb407f25f449ffd2a42d11325081b0c1e19 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,7 @@ OpenLDAP 2.4.20 Engineering
        Fixed slapd debug handling of LDAP_DEBUG_ANY (ITS#6324)
        Fixed slapd-ldap leak (ITS#6326)
        Fixed slapo-memberof operational attr updates (ITS#6329)
+       Fixed slapo-syncprov deadlock (ITS#6335)
        Documentation
                ldap_get_dn(3) typos (ITS#5366)
 
index ddb060d88831df6335f18e6584edcabaedffbaee..651973c8d477e84594cc43e6fa62808aeb46d5c1 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;