In bdb_cache_add use a readlock outside the txn to protect the entry

until send_ldap_result completes.
This commit is contained in:
Howard Chu 2006-12-30 12:05:55 +00:00
parent 6f571451ef
commit e844a6956d
3 changed files with 19 additions and 17 deletions

View File

@ -35,7 +35,7 @@ bdb_add(Operation *op, SlapReply *rs )
DB_TXN *ltid = NULL, *lt2; DB_TXN *ltid = NULL, *lt2;
struct bdb_op_info opinfo = {0}; struct bdb_op_info opinfo = {0};
int subentry; int subentry;
u_int32_t locker = 0; u_int32_t locker = 0, rlocker = 0;
DB_LOCK lock; DB_LOCK lock;
int num_retries = 0; int num_retries = 0;
@ -128,6 +128,9 @@ txnReturn:
goto return_results; goto return_results;
} }
/* Get our thread locker ID */
rs->sr_err = LOCK_ID( bdb->bi_dbenv, &rlocker );
if( 0 ) { if( 0 ) {
retry: /* transaction retry */ retry: /* transaction retry */
if( p ) { if( p ) {
@ -424,7 +427,8 @@ retry: /* transaction retry */
nrdn = op->ora_e->e_nname; nrdn = op->ora_e->e_nname;
} }
bdb_cache_add( bdb, ei, op->ora_e, &nrdn, locker ); /* Use the thread locker here, outside the txn */
bdb_cache_add( bdb, ei, op->ora_e, &nrdn, rlocker, &lock );
if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) { if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {
rs->sr_text = "txn_commit failed"; rs->sr_text = "txn_commit failed";
@ -461,27 +465,26 @@ return_results:
} }
op->o_private = NULL; op->o_private = NULL;
if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) {
slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
}
if( rs->sr_err == LDAP_SUCCESS ) { if( rs->sr_err == LDAP_SUCCESS ) {
EntryInfo *ei = oe->e_private;
/* We own the entry now, and it can be purged at will /* We own the entry now, and it can be purged at will
* Check to make sure it's the same entry we entered with. * Check to make sure it's the same entry we entered with.
* Possibly a callback may have mucked with it, although * Possibly a callback may have mucked with it, although
* in general callbacks should treat the entry as read-only. * in general callbacks should treat the entry as read-only.
*/ */
bdb_cache_return_entry_r( bdb->bi_dbenv, &bi->bi_cache, oe, &lock );
if ( op->ora_e == oe ) if ( op->ora_e == oe )
op->ora_e = NULL; op->ora_e = NULL;
ei->bei_state ^= CACHE_ENTRY_NOT_LINKED;
if ( bdb->bi_txn_cp_kbyte ) { if ( bdb->bi_txn_cp_kbyte ) {
TXN_CHECKPOINT( bdb->bi_dbenv, TXN_CHECKPOINT( bdb->bi_dbenv,
bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 ); bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
} }
} }
if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) {
slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
}
return rs->sr_err; return rs->sr_err;
} }

View File

@ -886,10 +886,10 @@ bdb_cache_add(
EntryInfo *eip, EntryInfo *eip,
Entry *e, Entry *e,
struct berval *nrdn, struct berval *nrdn,
u_int32_t locker ) u_int32_t locker,
DB_LOCK *lock )
{ {
EntryInfo *new, ei; EntryInfo *new, ei;
DB_LOCK lock;
int rc; int rc;
#ifdef BDB_HIER #ifdef BDB_HIER
struct berval rdn = e->e_name; struct berval rdn = e->e_name;
@ -903,7 +903,7 @@ bdb_cache_add(
/* Lock this entry so that bdb_add can run to completion. /* Lock this entry so that bdb_add can run to completion.
* It can only fail if BDB has run out of lock resources. * It can only fail if BDB has run out of lock resources.
*/ */
rc = bdb_cache_entry_db_lock( bdb->bi_dbenv, locker, &ei, 1, 0, &lock ); rc = bdb_cache_entry_db_lock( bdb->bi_dbenv, locker, &ei, 0, 0, lock );
if ( rc ) { if ( rc ) {
bdb_cache_entryinfo_unlock( eip ); bdb_cache_entryinfo_unlock( eip );
return rc; return rc;
@ -931,9 +931,7 @@ bdb_cache_add(
} }
new->bei_e = e; new->bei_e = e;
e->e_private = new; e->e_private = new;
/* Set "Not linked" status so LRU purger ignores it */ new->bei_state = CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS;
new->bei_state = CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS |
CACHE_ENTRY_NOT_LINKED;
eip->bei_state &= ~CACHE_ENTRY_NO_KIDS; eip->bei_state &= ~CACHE_ENTRY_NO_KIDS;
if (eip->bei_parent) { if (eip->bei_parent) {
eip->bei_parent->bei_state &= ~CACHE_ENTRY_NO_GRANDKIDS; eip->bei_parent->bei_state &= ~CACHE_ENTRY_NO_GRANDKIDS;

View File

@ -499,7 +499,8 @@ int bdb_cache_add(
EntryInfo *pei, EntryInfo *pei,
Entry *e, Entry *e,
struct berval *nrdn, struct berval *nrdn,
u_int32_t locker u_int32_t locker,
DB_LOCK *lock
); );
int bdb_cache_modrdn( int bdb_cache_modrdn(
struct bdb_info *bdb, struct bdb_info *bdb,