ITS#5728 release entries before send_ldap_ber()

This commit is contained in:
Howard Chu 2008-10-07 00:40:52 +00:00
parent 9d84e97bbc
commit cfc8c67523
3 changed files with 64 additions and 13 deletions

View file

@ -212,18 +212,22 @@ struct bdb_info {
struct bdb_lock_info {
struct bdb_lock_info *bli_next;
ID bli_id;
DB_LOCK bli_lock;
ID bli_id;
int bli_flag;
};
#define BLI_DONTFREE 1
struct bdb_op_info {
BackendDB* boi_bdb;
DB_TXN* boi_txn;
struct bdb_lock_info *boi_locks; /* used when no txn */
u_int32_t boi_err;
u_int32_t boi_locker;
int boi_acl_cache;
struct bdb_lock_info *boi_locks; /* used when no txn */
char boi_acl_cache;
char boi_flag;
};
#define BOI_DONTFREE 1
#define DB_OPEN(db, file, name, type, flags, mode) \
((db)->open)(db, file, name, type, flags, mode)

View file

@ -271,12 +271,17 @@ int bdb_entry_release(
bdb_cache_return_entry_rw( bdb->bi_dbenv, &bdb->bi_cache,
e, rw, &bli->bli_lock );
prev->bli_next = bli->bli_next;
op->o_tmpfree( bli, op->o_tmpmemctx );
/* Cleanup, or let caller know we unlocked */
if (bli->bli_flag & BLI_DONTFREE)
bli->bli_flag = 0;
else
op->o_tmpfree( bli, op->o_tmpmemctx );
break;
}
}
if ( !boi->boi_locks ) {
op->o_tmpfree( boi, op->o_tmpmemctx );
if ( !(boi->boi_flag & BOI_DONTFREE))
op->o_tmpfree( boi, op->o_tmpmemctx );
op->o_private = NULL;
}
}

View file

@ -837,6 +837,14 @@ fetch_entry_retry:
op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL
? LDAP_SCOPE_BASE : LDAP_SCOPE_SUBTREE );
/* free reader lock */
#ifdef SLAP_ZONE_ALLOC
slap_zn_runlock(bdb->bi_cache.c_zctx, e);
#endif
bdb_cache_return_entry_r( bdb->bi_dbenv,
&bdb->bi_cache, e , &lock );
e = NULL;
send_search_reference( op, rs );
ber_bvarray_free( rs->sr_ref );
@ -870,14 +878,55 @@ fetch_entry_retry:
}
if (e) {
struct bdb_op_info bois, *boi2;
struct bdb_lock_info blis;
/* Must set lockinfo so that entry_release will work */
if (!opinfo) {
boi2 = &bois;
op->o_private = boi2;
bois.boi_bdb = op->o_bd;
bois.boi_txn = NULL;
bois.boi_locker = locker;
bois.boi_err = 0;
bois.boi_locks = &blis;
blis.bli_next = NULL;
bois.boi_flag = BOI_DONTFREE;
} else {
boi2 = opinfo;
blis.bli_next = boi2->boi_locks;
boi2->boi_locks = &blis;
}
blis.bli_id = e->e_id;
blis.bli_lock = lock;
blis.bli_flag = BLI_DONTFREE;
/* safe default */
rs->sr_attrs = op->oq_search.rs_attrs;
rs->sr_operational_attrs = NULL;
rs->sr_ctrls = NULL;
rs->sr_flags = 0;
rs->sr_flags = REP_ENTRY_MUSTRELEASE;
rs->sr_err = LDAP_SUCCESS;
rs->sr_err = send_search_entry( op, rs );
/* send_search_entry will usually free it.
* an overlay might leave its own copy here;
* bli_flag will be 0 if lock was already released.
*/
if ( blis.bli_flag ) {
#ifdef SLAP_ZONE_ALLOC
slap_zn_runlock(bdb->bi_cache.c_zctx, e);
#endif
bdb_cache_return_entry_r(bdb->bi_dbenv,
&bdb->bi_cache, e, &lock);
op->o_private = opinfo;
if ( opinfo ) {
opinfo->boi_locks = blis.bli_next;
}
}
rs->sr_entry = NULL;
e = NULL;
switch ( rs->sr_err ) {
case LDAP_SUCCESS: /* entry sent ok */
break;
@ -885,13 +934,6 @@ fetch_entry_retry:
break;
case LDAP_UNAVAILABLE:
case LDAP_SIZELIMIT_EXCEEDED:
#ifdef SLAP_ZONE_ALLOC
slap_zn_runlock(bdb->bi_cache.c_zctx, e);
#endif
bdb_cache_return_entry_r(bdb->bi_dbenv,
&bdb->bi_cache, e, &lock);
e = NULL;
rs->sr_entry = NULL;
if ( rs->sr_err == LDAP_SIZELIMIT_EXCEEDED ) {
rs->sr_ref = rs->sr_v2ref;
send_ldap_result( op, rs );