/* syncprov.c - syncrepl provider */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2004-2013 The OpenLDAP Foundation.
+ * Copyright 2004-2014 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
fop.o_hdr = op->o_hdr;
fop.o_time = op->o_time;
fop.o_tincr = op->o_tincr;
+ fop.o_extra = op->o_extra;
cb.sc_response = findbase_cb;
cb.sc_private = fc;
fop.o_sync_mode = 0; /* turn off sync mode */
fop.o_managedsait = SLAP_CONTROL_CRITICAL;
fop.o_callback = &cb;
- LDAP_SLIST_INIT( &fop.o_extra );
fop.o_tag = LDAP_REQ_SEARCH;
fop.ors_scope = LDAP_SCOPE_BASE;
fop.ors_limit = NULL;
return i;
}
-static void
+static int
syncprov_free_syncop( syncops *so )
{
syncres *sr, *srnext;
/* already being freed, or still in use */
if ( !so->s_inuse || --so->s_inuse > 0 ) {
ldap_pvt_thread_mutex_unlock( &so->s_mutex );
- return;
+ return 0;
}
ldap_pvt_thread_mutex_unlock( &so->s_mutex );
if ( so->s_flags & PS_IS_DETACHED ) {
}
ldap_pvt_thread_mutex_destroy( &so->s_mutex );
ch_free( so );
+ return 1;
}
/* Send a persistent search response */
if ( lock )
ldap_pvt_thread_mutex_unlock( &so->s_op->o_conn->c_mutex );
}
- syncprov_free_syncop( so );
-
- return 0;
+ return syncprov_free_syncop( so );
}
static int
{
slap_callback *sc = op->o_callback;
op->o_callback = sc->sc_next;
- syncprov_drop_psearch( op->o_callback->sc_private, 0 );
+ syncprov_drop_psearch( sc->sc_private, 0 );
op->o_tmpfree( sc, op->o_tmpmemctx );
return 0;
}
syncprov_info_t *si = on->on_bi.bi_private;
fbase_cookie fc;
- syncops *ss, *sprev, *snext;
+ syncops **pss;
Entry *e = NULL;
Attribute *a;
- int rc;
+ int rc, gonext;
struct berval newdn;
int freefdn = 0;
BackendDB *b0 = op->o_bd, db;
}
ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
- for (ss = si->si_ops, sprev = (syncops *)&si->si_ops; ss;
- sprev = ss, ss=snext)
+ for (pss = &si->si_ops; *pss; pss = gonext ? &(*pss)->s_next : pss)
{
Operation op2;
Opheader oh;
syncmatches *sm;
int found = 0;
+ syncops *snext, *ss = *pss;
- snext = ss->s_next;
+ gonext = 1;
if ( ss->s_op->o_abandon )
continue;
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, 1 );
- ss = sprev;
+ snext = ss->s_next;
+ if ( syncprov_drop_psearch( ss, 1 ) )
+ *pss = snext;
+ gonext = 0;
continue;
}
phase otherwise (ITS#6555) */
op2.ors_filter = ss->s_op->ors_filter->f_and->f_next;
}
- ldap_pvt_thread_mutex_unlock( &ss->s_mutex );
rc = test_filter( &op2, e, op2.ors_filter );
+ ldap_pvt_thread_mutex_unlock( &ss->s_mutex );
}
Debug( LDAP_DEBUG_TRACE, "syncprov_matchops: sid %03x fscope %d rc %d\n",
/* Decrement s_inuse, was incremented when called
* with saveit == TRUE
*/
- syncprov_free_syncop( ss );
+ snext = ss->s_next;
+ if ( syncprov_free_syncop( ss ) ) {
+ *pss = snext;
+ gonext = 0;
+ }
}
}
ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
#ifdef SLAP_CONFIG_DELETE
if ( !slapd_shutdown ) {
+ ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
for ( so=si->si_ops, sonext=so; so; so=sonext ) {
SlapReply rs = {REP_RESULT};
rs.sr_err = LDAP_UNAVAILABLE;
syncprov_drop_psearch( so, 0);
}
si->si_ops=NULL;
+ ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
}
overlay_unregister_control( be, LDAP_CONTROL_SYNC );
#endif /* SLAP_CONFIG_DELETE */