]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/syncprov.c
Sync with HEAD
[openldap] / servers / slapd / overlays / syncprov.c
index aa51bcd07ec7b094db044e0d1023dba82b368cb3..c406f5b1fa7fe206f4d7c93da9a7aa9c9c9c44da 100644 (file)
@@ -860,6 +860,16 @@ syncprov_drop_psearch( syncops *so, int lock )
        return 0;
 }
 
+static int
+syncprov_ab_cleanup( Operation *op, SlapReply *rs )
+{
+       slap_callback *sc = op->o_callback;
+       op->o_callback = sc->sc_next;
+       syncprov_drop_psearch( op->o_callback->sc_private, 0 );
+       op->o_tmpfree( sc, op->o_tmpmemctx );
+       return 0;
+}
+
 static int
 syncprov_op_abandon( Operation *op, SlapReply *rs )
 {
@@ -881,8 +891,17 @@ syncprov_op_abandon( Operation *op, SlapReply *rs )
        if ( so ) {
                /* Is this really a Cancel exop? */
                if ( op->o_tag != LDAP_REQ_ABANDON ) {
+                       so->s_op->o_cancel = SLAP_CANCEL_ACK;
                        rs->sr_err = LDAP_CANCELLED;
                        send_ldap_result( so->s_op, rs );
+                       if ( so->s_flags & PS_IS_DETACHED ) {
+                               slap_callback *cb;
+                               cb = op->o_tmpcalloc( 1, sizeof(slap_callback), op->o_tmpmemctx );
+                               cb->sc_cleanup = syncprov_ab_cleanup;
+                               cb->sc_next = op->o_callback;
+                               cb->sc_private = so;
+                               return SLAP_CB_CONTINUE;
+                       }
                }
                syncprov_drop_psearch( so, 0 );
        }
@@ -1468,6 +1487,18 @@ syncprov_op_mod( Operation *op, SlapReply *rs )
                                ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );
                                ldap_pvt_thread_yield();
                                ldap_pvt_thread_mutex_lock( &mt->mt_mutex );
+
+                               /* clean up if the caller is giving up */
+                               if ( op->o_abandon ) {
+                                       modinst *m2;
+                                       for ( m2 = mt->mt_mods; m2->mi_next != mi;
+                                               m2 = m2->mi_next );
+                                       m2->mi_next = mi->mi_next;
+                                       if ( mt->mt_tail == mi ) mt->mt_tail = m2;
+                                       op->o_tmpfree( cb, op->o_tmpmemctx );
+                                       ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );
+                                       return SLAPD_ABANDON;
+                               }
                        }
                        ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );
                } else {