]> git.sur5r.net Git - openldap/commitdiff
Force a refresh if the search base has changed
authorHoward Chu <hyc@openldap.org>
Sat, 27 Nov 2004 07:47:24 +0000 (07:47 +0000)
committerHoward Chu <hyc@openldap.org>
Sat, 27 Nov 2004 07:47:24 +0000 (07:47 +0000)
servers/slapd/overlays/syncprov.c

index d61061faa6738aa33aa7c939e4acf4a3d82781b9..61a7fa71a6156181ef4872e9d61e24538e13b5e1 100644 (file)
@@ -780,6 +780,68 @@ syncprov_sendresp( Operation *op, opcookie *opc, syncops *so, Entry *e, int mode
        return rs.sr_err;
 }
 
+static void
+syncprov_free_syncop( syncops *so )
+{
+       syncres *sr, *srnext;
+
+       ldap_pvt_thread_mutex_lock( &so->s_mutex );
+       so->s_inuse--;
+       if ( so->s_inuse > 0 ) {
+               ldap_pvt_thread_mutex_unlock( &so->s_mutex );
+               return;
+       }
+       ldap_pvt_thread_mutex_unlock( &so->s_mutex );
+       filter_free( so->s_op->ors_filter );
+       ch_free( so->s_op );
+       ch_free( so->s_base.bv_val );
+       for ( sr=so->s_res; sr; sr=srnext ) {
+               srnext = sr->s_next;
+               ch_free( sr );
+       }
+       ldap_pvt_thread_mutex_destroy( &so->s_mutex );
+       ch_free( so );
+}
+
+static int
+syncprov_drop_psearch( syncops *so )
+{
+       ldap_pvt_thread_mutex_lock( &so->s_op->o_conn->c_mutex );
+       so->s_op->o_conn->c_n_ops_executing--;
+       so->s_op->o_conn->c_n_ops_completed++;
+       ldap_pvt_thread_mutex_unlock( &so->s_op->o_conn->c_mutex );
+       syncprov_free_syncop( so );
+}
+
+static int
+syncprov_op_abandon( Operation *op, SlapReply *rs )
+{
+       slap_overinst           *on = (slap_overinst *)op->o_bd->bd_info;
+       syncprov_info_t         *si = on->on_bi.bi_private;
+       syncops *so, *soprev;
+
+       ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
+       for ( so=si->si_ops, soprev = (syncops *)&si->si_ops; so;
+               soprev=so, so=so->s_next ) {
+               if ( so->s_op->o_connid == op->o_connid &&
+                       so->s_op->o_msgid == op->orn_msgid ) {
+                               so->s_op->o_abandon = 1;
+                               soprev->s_next = so->s_next;
+                               break;
+               }
+       }
+       ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
+       if ( so ) {
+               /* Is this really a Cancel exop? */
+               if ( op->o_tag != LDAP_REQ_ABANDON ) {
+                       rs->sr_err = LDAP_CANCELLED;
+                       send_ldap_result( so->s_op, rs );
+               }
+               syncprov_drop_psearch( so );
+       }
+       return SLAP_CB_CONTINUE;
+}
+
 /* Find which persistent searches are affected by this operation */
 static void
 syncprov_matchops( Operation *op, opcookie *opc, int saveit )
@@ -788,7 +850,7 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit )
        syncprov_info_t         *si = on->on_bi.bi_private;
 
        fbase_cookie fc;
-       syncops *ss;
+       syncops *ss, *sprev, *snext;
        Entry *e;
        Attribute *a;
        int rc;
@@ -824,17 +886,28 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit )
        }
 
        ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
-       for (ss = si->si_ops; ss; ss=ss->s_next)
+       for (ss = si->si_ops, sprev = (syncops *)&si->si_ops; ss;
+               sprev = ss, ss=snext)
        {
                syncmatches *sm;
                int found = 0;
 
+               snext = ss->s_next;
                /* validate base */
                fc.fss = ss;
                fc.fbase = 0;
                fc.fscope = 0;
+
+               /* If the base of the search is missing, signal a refresh */
                rc = syncprov_findbase( op, &fc );
-               if ( rc != LDAP_SUCCESS ) continue;
+               if ( rc != LDAP_SUCCESS ) {
+                       SlapReply rs = {REP_RESULT};
+                       send_ldap_error( ss->s_op, &rs, LDAP_SYNC_REFRESH_REQUIRED,
+                               "search base has changed" );
+                       sprev->s_next = snext;
+                       syncprov_drop_psearch( ss );
+                       continue;
+               }
 
                /* If we're sending results now, look for this op in old matches */
                if ( !saveit ) {
@@ -877,29 +950,6 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit )
        }
 }
 
-static void
-syncprov_free_syncop( syncops *so )
-{
-       syncres *sr, *srnext;
-
-       ldap_pvt_thread_mutex_lock( &so->s_mutex );
-       so->s_inuse--;
-       if ( so->s_inuse > 0 ) {
-               ldap_pvt_thread_mutex_unlock( &so->s_mutex );
-               return;
-       }
-       ldap_pvt_thread_mutex_unlock( &so->s_mutex );
-       filter_free( so->s_op->ors_filter );
-       ch_free( so->s_op );
-       ch_free( so->s_base.bv_val );
-       for ( sr=so->s_res; sr; sr=srnext ) {
-               srnext = sr->s_next;
-               ch_free( sr );
-       }
-       ldap_pvt_thread_mutex_destroy( &so->s_mutex );
-       ch_free( so );
-}
-
 static int
 syncprov_op_cleanup( Operation *op, SlapReply *rs )
 {
@@ -1000,39 +1050,6 @@ syncprov_op_response( Operation *op, SlapReply *rs )
        return SLAP_CB_CONTINUE;
 }
 
-static int
-syncprov_op_abandon( Operation *op, SlapReply *rs )
-{
-       slap_overinst           *on = (slap_overinst *)op->o_bd->bd_info;
-       syncprov_info_t         *si = on->on_bi.bi_private;
-       syncops *so, *soprev;
-
-       ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
-       for ( so=si->si_ops, soprev = (syncops *)&si->si_ops; so;
-               soprev=so, so=so->s_next ) {
-               if ( so->s_op->o_connid == op->o_connid &&
-                       so->s_op->o_msgid == op->orn_msgid ) {
-                               so->s_op->o_abandon = 1;
-                               soprev->s_next = so->s_next;
-                               break;
-               }
-       }
-       ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
-       if ( so ) {
-               ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
-               op->o_conn->c_n_ops_executing--;
-               op->o_conn->c_n_ops_completed++;
-               ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
-               /* Is this really a Cancel exop? */
-               if ( op->o_tag != LDAP_REQ_ABANDON ) {
-                       rs->sr_err = LDAP_CANCELLED;
-                       send_ldap_result( so->s_op, rs );
-               }
-               syncprov_free_syncop( so );
-       }
-       return SLAP_CB_CONTINUE;
-}
-
 #if 0
 /* We don't use a subentry to store the context CSN any more. But
  * we ought to expose the current context CSN as an operational attribute