mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-30 13:30:57 +08:00
experimental fix to callback looping
This commit is contained in:
parent
92b1ad358d
commit
44e3b0b481
@ -286,6 +286,114 @@ send_ldap_controls( Operation *o, BerElement *ber, LDAPControl **c )
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
slap_response_loop(
|
||||||
|
Operation *op,
|
||||||
|
SlapReply *rs )
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
#ifdef NEW_CB
|
||||||
|
slap_callback *sc = op->o_callback, **sc_prev;
|
||||||
|
|
||||||
|
rc = SLAP_CB_CONTINUE;
|
||||||
|
for ( sc_prev = ≻ *sc_prev; ) {
|
||||||
|
slap_callback **sc_next = &(*sc_prev)->sc_next;
|
||||||
|
|
||||||
|
op->o_callback = *sc_prev;
|
||||||
|
if ( op->o_callback->sc_response ) {
|
||||||
|
rc = op->o_callback->sc_response( op, rs );
|
||||||
|
if ( op->o_callback == NULL ) {
|
||||||
|
/* the callback has been removed; repair the list */
|
||||||
|
*sc_prev = *sc_next;
|
||||||
|
|
||||||
|
} else if ( op->o_callback != *sc_prev ) {
|
||||||
|
/* a new callback has been inserted; repair the list */
|
||||||
|
*sc_next = op->o_callback;
|
||||||
|
sc_next = &op->o_callback;
|
||||||
|
}
|
||||||
|
if ( rc != SLAP_CB_CONTINUE ) break;
|
||||||
|
}
|
||||||
|
sc_prev = sc_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
op->o_callback = sc;
|
||||||
|
#else /* ! NEW_CB */
|
||||||
|
slap_callback *sc = op->o_callback, **sc_prev = &sc, *sc_next;
|
||||||
|
|
||||||
|
rc = SLAP_CB_CONTINUE;
|
||||||
|
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
|
||||||
|
sc_next = op->o_callback->sc_next;
|
||||||
|
if ( op->o_callback->sc_response ) {
|
||||||
|
slap_callback *sc2 = op->o_callback;
|
||||||
|
rc = op->o_callback->sc_response( op, rs );
|
||||||
|
if ( op->o_callback != sc2 ) {
|
||||||
|
*sc_prev = op->o_callback;
|
||||||
|
}
|
||||||
|
if ( rc != SLAP_CB_CONTINUE || !op->o_callback ) break;
|
||||||
|
if ( op->o_callback != sc2 ) continue;
|
||||||
|
}
|
||||||
|
sc_prev = &op->o_callback->sc_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
op->o_callback = sc;
|
||||||
|
#endif /* ! NEW_CB */
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
slap_cleanup_loop(
|
||||||
|
Operation *op,
|
||||||
|
SlapReply *rs )
|
||||||
|
{
|
||||||
|
#ifdef NEW_CB
|
||||||
|
slap_callback *sc = op->o_callback, **sc_prev;
|
||||||
|
|
||||||
|
for ( sc_prev = ≻ *sc_prev; ) {
|
||||||
|
slap_callback **sc_next = &(*sc_prev)->sc_next;
|
||||||
|
|
||||||
|
op->o_callback = *sc_prev;
|
||||||
|
if ( op->o_callback->sc_cleanup ) {
|
||||||
|
(void)op->o_callback->sc_cleanup( op, rs );
|
||||||
|
if ( op->o_callback == NULL ) {
|
||||||
|
/* the callback has been removed; repair the list */
|
||||||
|
*sc_prev = *sc_next;
|
||||||
|
|
||||||
|
} else if ( op->o_callback != *sc_prev ) {
|
||||||
|
/* a new callback has been inserted; repair the list */
|
||||||
|
*sc_next = op->o_callback;
|
||||||
|
sc_next = &op->o_callback;
|
||||||
|
}
|
||||||
|
/* don't care about the result; do all cleanup */
|
||||||
|
}
|
||||||
|
sc_prev = sc_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
op->o_callback = sc;
|
||||||
|
#else /* ! NEW_CB */
|
||||||
|
slap_callback *sc = op->o_callback, **sc_prev = &sc, *sc_next;
|
||||||
|
|
||||||
|
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
|
||||||
|
sc_next = op->o_callback->sc_next;
|
||||||
|
if ( op->o_callback->sc_cleanup ) {
|
||||||
|
slap_callback *sc2 = op->o_callback;
|
||||||
|
(void)op->o_callback->sc_cleanup( op, rs );
|
||||||
|
if ( op->o_callback != sc2 ) {
|
||||||
|
*sc_prev = op->o_callback;
|
||||||
|
}
|
||||||
|
if ( !op->o_callback ) break;
|
||||||
|
if ( op->o_callback != sc2 ) continue;
|
||||||
|
}
|
||||||
|
sc_prev = &op->o_callback->sc_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
op->o_callback = sc;
|
||||||
|
#endif /* ! NEW_CB */
|
||||||
|
|
||||||
|
return LDAP_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
send_ldap_response(
|
send_ldap_response(
|
||||||
Operation *op,
|
Operation *op,
|
||||||
@ -302,25 +410,10 @@ send_ldap_response(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( op->o_callback ) {
|
if ( op->o_callback ) {
|
||||||
slap_callback *sc = op->o_callback, **sc_prev = &sc, *sc_next;
|
rc = slap_response_loop( op, rs );
|
||||||
|
if ( rc != SLAP_CB_CONTINUE ) {
|
||||||
rc = SLAP_CB_CONTINUE;
|
goto clean2;
|
||||||
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
|
|
||||||
sc_next = op->o_callback->sc_next;
|
|
||||||
if ( op->o_callback->sc_response ) {
|
|
||||||
slap_callback *sc2 = op->o_callback;
|
|
||||||
rc = op->o_callback->sc_response( op, rs );
|
|
||||||
if ( op->o_callback != sc2 ) {
|
|
||||||
*sc_prev = op->o_callback;
|
|
||||||
}
|
|
||||||
if ( rc != SLAP_CB_CONTINUE || !op->o_callback ) break;
|
|
||||||
if ( op->o_callback != sc2 ) continue;
|
|
||||||
}
|
|
||||||
sc_prev = &op->o_callback->sc_next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op->o_callback = sc;
|
|
||||||
if ( rc != SLAP_CB_CONTINUE ) goto clean2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LDAP_CONNECTIONLESS
|
#ifdef LDAP_CONNECTIONLESS
|
||||||
@ -458,25 +551,9 @@ cleanup:;
|
|||||||
|
|
||||||
clean2:;
|
clean2:;
|
||||||
if ( op->o_callback ) {
|
if ( op->o_callback ) {
|
||||||
slap_callback *sc = op->o_callback, **sc_prev = &sc, *sc_next;
|
(void)slap_cleanup_loop( op, rs );
|
||||||
|
|
||||||
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
|
|
||||||
sc_next = op->o_callback->sc_next;
|
|
||||||
if ( op->o_callback->sc_cleanup ) {
|
|
||||||
slap_callback *sc2 = op->o_callback;
|
|
||||||
(void)op->o_callback->sc_cleanup( op, rs );
|
|
||||||
if ( op->o_callback != sc2 ) {
|
|
||||||
*sc_prev = op->o_callback;
|
|
||||||
}
|
|
||||||
if ( !op->o_callback ) break;
|
|
||||||
if ( op->o_callback != sc2 ) continue;
|
|
||||||
}
|
|
||||||
sc_prev = &op->o_callback->sc_next;
|
|
||||||
}
|
|
||||||
op->o_callback = sc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( rs->sr_matched && rs->sr_flags & REP_MATCHED_MUSTBEFREED ) {
|
if ( rs->sr_matched && rs->sr_flags & REP_MATCHED_MUSTBEFREED ) {
|
||||||
free( (char *)rs->sr_matched );
|
free( (char *)rs->sr_matched );
|
||||||
rs->sr_matched = NULL;
|
rs->sr_matched = NULL;
|
||||||
@ -715,26 +792,10 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( op->o_callback ) {
|
if ( op->o_callback ) {
|
||||||
slap_callback *sc = op->o_callback, **sc_prev = &sc, *sc_next;
|
rc = slap_response_loop( op, rs );
|
||||||
|
if ( rc != SLAP_CB_CONTINUE ) {
|
||||||
rc = SLAP_CB_CONTINUE;
|
goto error_return;
|
||||||
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next )
|
|
||||||
{
|
|
||||||
sc_next = op->o_callback->sc_next;
|
|
||||||
if ( op->o_callback->sc_response ) {
|
|
||||||
slap_callback *sc2 = op->o_callback;
|
|
||||||
rc = op->o_callback->sc_response( op, rs );
|
|
||||||
if ( op->o_callback != sc2 ) {
|
|
||||||
*sc_prev = op->o_callback;
|
|
||||||
}
|
|
||||||
if ( rc != SLAP_CB_CONTINUE || !op->o_callback ) break;
|
|
||||||
if ( op->o_callback != sc2 ) continue;
|
|
||||||
}
|
|
||||||
sc_prev = &op->o_callback->sc_next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op->o_callback = sc;
|
|
||||||
if ( rc != SLAP_CB_CONTINUE ) goto error_return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> send_search_entry: conn %lu dn=\"%s\"%s\n",
|
Debug( LDAP_DEBUG_TRACE, "=> send_search_entry: conn %lu dn=\"%s\"%s\n",
|
||||||
@ -1173,22 +1234,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
|
|||||||
|
|
||||||
error_return:;
|
error_return:;
|
||||||
if ( op->o_callback ) {
|
if ( op->o_callback ) {
|
||||||
slap_callback *sc = op->o_callback, **sc_prev = &sc, *sc_next;
|
(void)slap_cleanup_loop( op, rs );
|
||||||
|
|
||||||
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
|
|
||||||
sc_next = op->o_callback->sc_next;
|
|
||||||
if ( op->o_callback->sc_cleanup ) {
|
|
||||||
slap_callback *sc2 = op->o_callback;
|
|
||||||
(void)op->o_callback->sc_cleanup( op, rs );
|
|
||||||
if ( op->o_callback != sc2 ) {
|
|
||||||
*sc_prev = op->o_callback;
|
|
||||||
}
|
|
||||||
if ( !op->o_callback ) break;
|
|
||||||
if ( op->o_callback != sc2 ) continue;
|
|
||||||
}
|
|
||||||
sc_prev = &op->o_callback->sc_next;
|
|
||||||
}
|
|
||||||
op->o_callback = sc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( e_flags ) {
|
if ( e_flags ) {
|
||||||
@ -1232,25 +1278,10 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
|
|||||||
|
|
||||||
rs->sr_type = REP_SEARCHREF;
|
rs->sr_type = REP_SEARCHREF;
|
||||||
if ( op->o_callback ) {
|
if ( op->o_callback ) {
|
||||||
slap_callback *sc = op->o_callback, **sc_prev = &sc, *sc_next;
|
rc = slap_response_loop( op, rs );
|
||||||
|
if ( rc != SLAP_CB_CONTINUE ) {
|
||||||
rc = SLAP_CB_CONTINUE;
|
goto rel;
|
||||||
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
|
|
||||||
sc_next = op->o_callback->sc_next;
|
|
||||||
if ( op->o_callback->sc_response ) {
|
|
||||||
slap_callback *sc2 = op->o_callback;
|
|
||||||
rc = op->o_callback->sc_response( op, rs );
|
|
||||||
if ( op->o_callback != sc2 ) {
|
|
||||||
*sc_prev = op->o_callback;
|
|
||||||
}
|
|
||||||
if ( rc != SLAP_CB_CONTINUE || !op->o_callback ) break;
|
|
||||||
if ( op->o_callback != sc2 ) continue;
|
|
||||||
}
|
|
||||||
sc_prev = &op->o_callback->sc_next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op->o_callback = sc;
|
|
||||||
if ( rc != SLAP_CB_CONTINUE ) goto rel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
@ -1376,22 +1407,7 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
|
|||||||
|
|
||||||
rel:
|
rel:
|
||||||
if ( op->o_callback ) {
|
if ( op->o_callback ) {
|
||||||
slap_callback *sc = op->o_callback, **sc_prev = &sc, *sc_next;
|
(void)slap_cleanup_loop( op, rs );
|
||||||
|
|
||||||
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
|
|
||||||
sc_next = op->o_callback->sc_next;
|
|
||||||
if ( op->o_callback->sc_cleanup ) {
|
|
||||||
slap_callback *sc2 = op->o_callback;
|
|
||||||
(void)op->o_callback->sc_cleanup( op, rs );
|
|
||||||
if ( op->o_callback != sc2 ) {
|
|
||||||
*sc_prev = op->o_callback;
|
|
||||||
}
|
|
||||||
if ( rc != SLAP_CB_CONTINUE || !op->o_callback ) break;
|
|
||||||
if ( op->o_callback != sc2 ) continue;
|
|
||||||
}
|
|
||||||
sc_prev = &op->o_callback->sc_next;
|
|
||||||
}
|
|
||||||
op->o_callback = sc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
Loading…
Reference in New Issue
Block a user