struct berval sndn;
struct berval suuid; /* UUID of entry */
struct berval sctxcsn;
- syncops *shead; /* head of si_ops when we started */
int sreference; /* Is the entry a reference? */
} opcookie;
opc.son = on;
op->o_bd->bd_info = (BackendInfo *)on->on_info;
for (sr = so->s_res; sr; sr=srnext) {
- int rc;
srnext = sr->s_next;
opc.sdn = sr->s_dn;
opc.sndn = sr->s_ndn;
Operation sop = *so->s_op;
Opheader ohdr;
+ if ( so->s_op->o_abandon )
+ return SLAPD_ABANDON;
+
ohdr = *sop.o_hdr;
sop.o_hdr = &ohdr;
sop.o_tmpmemctx = op->o_tmpmemctx;
op->o_tmpfree( rs.sr_ctrls[0], op->o_tmpmemctx );
op->o_private = sop.o_private;
rs.sr_ctrls = NULL;
+ /* Check queue again here; if we were hanging in a send and eventually
+ * recovered, there may be more to send now. But don't check if the
+ * original psearch has been abandoned.
+ */
+ if ( !so->s_op->o_abandon && rs.sr_err == LDAP_SUCCESS && queue
+ && so->s_res ) {
+ ldap_pvt_thread_mutex_lock( &so->s_mutex );
+ rs.sr_err = syncprov_qplay( &sop, on, so );
+ ldap_pvt_thread_mutex_unlock( &so->s_mutex );
+ }
return rs.sr_err;
}
if ( op->o_tag != LDAP_REQ_ADD ) {
op->o_bd->bd_info = (BackendInfo *)on->on_info;
rc = be_entry_get_rw( op, fc.fdn, NULL, NULL, 0, &e );
+ /* If we're sending responses now, make a copy and unlock the DB */
+ if ( e && !saveit ) {
+ Entry *e2 = entry_dup( e );
+ be_entry_release_rw( op, e, 0 );
+ e = e2;
+ }
op->o_bd->bd_info = (BackendInfo *)on;
if ( rc ) return;
} else {
ber_dupbv_x( &opc->suuid, &a->a_nvals[0], op->o_tmpmemctx );
}
- if (saveit) {
- ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
- opc->shead = si->si_ops;
- }
- for (ss = opc->shead, sprev = (syncops *)&si->si_ops; ss;
+ ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
+ for (ss = si->si_ops, sprev = (syncops *)&si->si_ops; ss;
sprev = ss, ss=snext)
{
syncmatches *sm;
opc->smatches = sm;
} else {
/* if found send UPDATE else send ADD */
+ ss->s_inuse++;
+ ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
syncprov_sendresp( op, opc, ss, &e,
found ? LDAP_SYNC_MODIFY : LDAP_SYNC_ADD, 1 );
+ ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
+ ss->s_inuse--;
}
} else if ( !saveit && found ) {
/* send DELETE */
+ ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
syncprov_sendresp( op, opc, ss, NULL, LDAP_SYNC_DELETE, 1 );
+ ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
}
}
- if (saveit)
- ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
+ ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
done:
if ( op->o_tag != LDAP_REQ_ADD && e ) {
op->o_bd->bd_info = (BackendInfo *)on->on_info;
mtdummy.mt_op = op;
ldap_pvt_thread_mutex_lock( &si->si_mods_mutex );
mt = avl_find( si->si_mods, &mtdummy, sp_avl_cmp );
- ldap_pvt_thread_mutex_unlock( &si->si_mods_mutex );
if ( mt ) {
modinst *mi = mt->mt_mods;
mt->mt_op = mt->mt_mods->mi_op;
ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );
} else {
- 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 );
ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );
ldap_pvt_thread_mutex_destroy( &mt->mt_mutex );
ch_free( mt );
}
}
+ ldap_pvt_thread_mutex_unlock( &si->si_mods_mutex );
if ( !BER_BVISNULL( &opc->suuid ))
op->o_tmpfree( opc->suuid.bv_val, op->o_tmpmemctx );
if ( !BER_BVISNULL( &opc->sndn ))