From 7710791382d62640e693213e12067aca7a4eeb8a Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sun, 19 Oct 2003 11:20:34 +0000 Subject: [PATCH] ITS#2684 keep psearch operations on the connection's active list so they can be located by connection_abandon() during an unexpected close. Remove the operations in bdb_abandon() etc. --- servers/slapd/back-bdb/search.c | 63 ++++++++++++++++++++------------- servers/slapd/connection.c | 10 ++---- 2 files changed, 42 insertions(+), 31 deletions(-) diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index 7e37aca405..39785dd96b 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -291,48 +291,60 @@ int is_sync_protocol( Operation *op ) ( type == LDAP_PSEARCH_BY_SCOPEOUT )) #define IS_PSEARCH (op != sop) -int -bdb_abandon( Operation *op, SlapReply *rs ) +static Operation * +bdb_drop_psearch( Operation *op, ber_int_t msgid ) { Operation *ps_list; struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) { if ( ps_list->o_connid == op->o_connid ) { - if ( ps_list->o_msgid == op->oq_abandon.rs_msgid ) { + if ( ps_list->o_msgid == msgid ) { ps_list->o_abandon = 1; LDAP_LIST_REMOVE( ps_list, o_ps_link ); - slap_op_free ( ps_list ); - return LDAP_SUCCESS; + ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); + LDAP_STAILQ_REMOVE( &op->o_conn->c_ops, ps_list, + slap_op, o_next ); + LDAP_STAILQ_NEXT( ps_list, o_next ) = NULL; + op->o_conn->c_n_ops_executing--; + op->o_conn->c_n_ops_completed++; + ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); + return ps_list; } } } - return LDAP_UNAVAILABLE; } int -bdb_cancel( Operation *op, SlapReply *rs ) +bdb_abandon( Operation *op, SlapReply *rs ) { - Operation *ps_list; - struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; - - LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) { - if ( ps_list->o_connid == op->o_connid ) { - if ( ps_list->o_msgid == op->oq_cancel.rs_msgid ) { - ps_list->o_cancel = SLAP_CANCEL_DONE; - LDAP_LIST_REMOVE( ps_list, o_ps_link ); + Operation *ps; - rs->sr_err = LDAP_CANCELLED; - send_ldap_result( ps_list, rs ); - - if ( ps_list->o_tmpmemctx ) { - sl_mem_destroy( NULL, ps_list->o_tmpmemctx ); - } + ps = bdb_drop_psearch( op, op->oq_abandon.rs_msgid ); + if ( ps ) { + if ( ps->o_tmpmemctx ) { + sl_mem_destroy( NULL, ps->o_tmpmemctx ); + } + slap_op_free ( ps ); + return LDAP_SUCCESS; + } + return LDAP_UNAVAILABLE; +} - slap_op_free ( ps_list ); - return LDAP_SUCCESS; - } +int +bdb_cancel( Operation *op, SlapReply *rs ) +{ + Operation *ps; + + ps = bdb_drop_psearch( op, op->oq_cancel.rs_msgid ); + if ( ps ) { + rs->sr_err = LDAP_CANCELLED; + send_ldap_result( ps, rs ); + if ( ps->o_tmpmemctx ) { + sl_mem_destroy( NULL, ps->o_tmpmemctx ); } + slap_op_free ( ps ); + return LDAP_SUCCESS; } return LDAP_UNAVAILABLE; } @@ -818,6 +830,9 @@ dn2entry_retry: loop_begin: /* check for abandon */ if ( sop->o_abandon ) { + if ( sop != op ) { + bdb_drop_psearch( sop, sop->o_msgid ); + } rs->sr_err = LDAP_SUCCESS; goto done; } diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index 731f46bc8c..5541a8f833 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -1082,17 +1082,13 @@ operations_error: ldap_pvt_thread_mutex_lock( &conn->c_mutex ); - LDAP_STAILQ_REMOVE( &conn->c_ops, op, slap_op, o_next); - LDAP_STAILQ_NEXT(op, o_next) = NULL; - - if ( op->o_cancel == SLAP_CANCEL_ACK ) - goto co_op_free; - if ( ( op->o_sync_mode & SLAP_SYNC_PERSIST ) ) { + if ( op->o_cancel != SLAP_CANCEL_ACK && ( op->o_sync_mode & SLAP_SYNC_PERSIST ) ) { sl_mem_detach( ctx, memctx ); goto no_co_op_free; } -co_op_free: + LDAP_STAILQ_REMOVE( &conn->c_ops, op, slap_op, o_next); + LDAP_STAILQ_NEXT(op, o_next) = NULL; conn->c_n_ops_executing--; conn->c_n_ops_completed++; -- 2.39.5