redesign of back-bdb locking :

cache entry is locked by Berkeley DB lock primitives.
This commit is contained in:
Jong Hyuk Choi 2002-05-31 20:49:19 +00:00
parent 55e925abe6
commit 7341dc5db6
17 changed files with 458 additions and 102 deletions

View File

@ -23,7 +23,7 @@ bdb_add(
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
struct berval pdn;
Entry *p = NULL;
int rc;
int rc, ret;
const char *text;
char textbuf[SLAP_TEXT_BUFLEN];
size_t textlen = sizeof textbuf;
@ -33,6 +33,8 @@ bdb_add(
#ifdef BDB_SUBENTRIES
int subentry;
#endif
u_int32_t locker;
DB_LOCK lock;
#if 0
u_int32_t lockid;
DB_LOCK lock;
@ -108,6 +110,8 @@ retry: /* transaction retry */
text = "internal error";
goto return_results;
}
locker = TXN_ID ( ltid );
#if 0
lockid = TXN_ID( ltid );
#endif
@ -142,7 +146,7 @@ retry: /* transaction retry */
#endif
/* get parent */
rc = bdb_dn2entry_r( be, ltid, &pdn, &p, &matched, 0 );
rc = bdb_dn2entry_r( be, ltid, &pdn, &p, &matched, 0, locker, &lock );
switch( rc ) {
case 0:
@ -169,7 +173,7 @@ retry: /* transaction retry */
refs = is_entry_referral( matched )
? get_entry_referrals( be, conn, op, matched )
: NULL;
bdb_cache_return_entry_r(&bdb->bi_cache, matched);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
matched = NULL;
} else {
@ -200,7 +204,7 @@ retry: /* transaction retry */
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
/* free parent and reader lock */
bdb_cache_return_entry_r( &bdb->bi_cache, p );
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, p, &lock );
p = NULL;
goto retry;
}
@ -262,7 +266,7 @@ retry: /* transaction retry */
matched_dn, NULL, refs, NULL );
ber_bvarray_free( refs );
bdb_cache_return_entry_r( &bdb->bi_cache, p );
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, p, &lock );
p = NULL;
goto done;
}
@ -275,7 +279,7 @@ retry: /* transaction retry */
#endif
/* free parent and reader lock */
bdb_cache_return_entry_r( &bdb->bi_cache, p );
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, p, &lock );
p = NULL;
} else {
@ -430,9 +434,22 @@ retry: /* transaction retry */
text = "txn_prepare failed";
} else {
ret = bdb_cache_add_entry_rw(bdb->bi_dbenv, &bdb->bi_cache, e, CACHE_WRITE_LOCK, locker, &lock);
#if 0
if ( bdb_cache_add_entry_rw(&bdb->bi_cache,
e, CACHE_WRITE_LOCK) != 0 )
{
#endif
switch ( ret ) {
case 0:
break;
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
default:
ret = LDAP_OTHER;
}
if ( ret ) {
if(( rc=TXN_ABORT( ltid )) != 0 ) {
text = "cache add & txn_abort failed";
} else {

View File

@ -39,6 +39,9 @@ bdb_attribute(
const char *entry_at_name = entry_at->ad_cname.bv_val;
AccessControlState acl_state = ACL_STATE_INIT;
u_int32_t locker;
DB_LOCK lock;
#ifdef NEW_LOGGING
LDAP_LOG(( "backend", LDAP_LEVEL_ARGS,
"bdb_attribute: gr dn: \"%s\"\n", entry_ndn->bv_val ));
@ -65,6 +68,11 @@ bdb_attribute(
txn = boi->boi_txn;
}
if ( txn != NULL )
locker = TXN_ID ( txn );
else
LOCK_ID ( bdb->bi_dbenv, &locker );
if (target != NULL && dn_match(&target->e_nname, entry_ndn)) {
/* we already have a LOCKED copy of the entry */
e = target;
@ -80,16 +88,23 @@ bdb_attribute(
} else {
dn2entry_retry:
/* can we find entry */
rc = bdb_dn2entry_r( be, NULL, entry_ndn, &e, NULL, 0 );
rc = bdb_dn2entry_r( be, NULL, entry_ndn, &e, NULL, 0, locker, &lock );
switch( rc ) {
case DB_NOTFOUND:
case 0:
break;
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto dn2entry_retry;
default:
if( txn != NULL ) {
boi->boi_err = rc;
}
else {
LOCK_ID_FREE( bdb->bi_dbenv, locker );
}
return (rc != LDAP_BUSY) ? LDAP_OTHER : LDAP_BUSY;
}
if (e == NULL) {
@ -102,6 +117,9 @@ bdb_attribute(
"=> bdb_attribute: cannot find entry: \"%s\"\n",
entry_ndn->bv_val, 0, 0 );
#endif
if ( txn == NULL ) {
LOCK_ID_FREE( bdb->bi_dbenv, locker );
}
return LDAP_NO_SUCH_OBJECT;
}
@ -205,7 +223,11 @@ bdb_attribute(
return_results:
if( target != e ) {
/* free entry */
bdb_cache_return_entry_r(&bdb->bi_cache, e);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
}
if ( txn == NULL ) {
LOCK_ID_FREE( bdb->bi_dbenv, locker );
}
#ifdef NEW_LOGGING

View File

@ -146,21 +146,27 @@ struct bdb_op_info {
#if DB_VERSION_MAJOR < 4
#define LOCK_DETECT(env,f,t,a) lock_detect(env, f, t, a)
#define LOCK_GET(env,i,f,o,m,l) lock_get(env, i, f, o, m, l)
#define LOCK_PUT(env,l) lock_put(env, l)
#define TXN_CHECKPOINT(env,k,m,f) txn_checkpoint(env, k, m, f)
#define TXN_BEGIN(env,p,t,f) txn_begin((env), p, t, f)
#define TXN_PREPARE(txn,gid) txn_prepare((txn), (gid))
#define TXN_COMMIT(txn,f) txn_commit((txn), (f))
#define TXN_ABORT(txn) txn_abort((txn))
#define TXN_ID(txn) txn_id(txn)
#define LOCK_ID(env, locker) lock_id(env, locker)
#define LOCK_ID_FREE(env, locker) lock_id_free(env, locker)
#else
#define LOCK_DETECT(env,f,t,a) (env)->lock_detect(env, f, t, a)
#define LOCK_GET(env,i,f,o,m,l) (env)->lock_get(env, i, f, o, m, l)
#define LOCK_PUT(env,l) (env)->lock_put(env, l)
#define TXN_CHECKPOINT(env,k,m,f) (env)->txn_checkpoint(env, k, m, f)
#define TXN_BEGIN(env,p,t,f) (env)->txn_begin((env), p, t, f)
#define TXN_PREPARE(txn,g) (txn)->prepare((txn), (g))
#define TXN_COMMIT(txn,f) (txn)->commit((txn), (f))
#define TXN_ABORT(txn) (txn)->abort((txn))
#define TXN_ID(txn) (txn)->id(txn)
#define LOCK_ID(env, locker) (env)->lock_id(env, locker)
#define LOCK_ID_FREE(env, locker) (env)->lock_id_free(env, locker)
#endif
LDAP_END_DECL

View File

@ -40,14 +40,20 @@ bdb_bind(
AttributeDescription *password = slap_schema.si_ad_userPassword;
u_int32_t locker;
DB_LOCK lock;
#ifdef NEW_LOGGING
LDAP_LOG (( "bind", LDAP_LEVEL_ARGS, "==> bdb_bind: dn: %s\n", dn->bv_val ));
#else
Debug( LDAP_DEBUG_ARGS, "==> bdb_bind: dn: %s\n", dn->bv_val, 0, 0);
#endif
LOCK_ID(bdb->bi_dbenv, &locker);
dn2entry_retry:
/* get entry */
rc = bdb_dn2entry_r( be, NULL, ndn, &e, &matched, 0 );
rc = bdb_dn2entry_r( be, NULL, ndn, &e, &matched, 0, locker, &lock );
switch(rc) {
case DB_NOTFOUND:
@ -56,10 +62,15 @@ bdb_bind(
case LDAP_BUSY:
send_ldap_result( conn, op, LDAP_BUSY,
NULL, "ldap server busy", NULL, NULL );
LOCK_ID_FREE(bdb->bi_dbenv, locker);
return LDAP_BUSY;
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto dn2entry_retry;
default:
send_ldap_result( conn, op, rc=LDAP_OTHER,
NULL, "internal error", NULL, NULL );
LOCK_ID_FREE(bdb->bi_dbenv, locker);
return rc;
}
@ -75,7 +86,7 @@ bdb_bind(
? get_entry_referrals( be, conn, op, matched )
: NULL;
bdb_cache_return_entry_r( &bdb->bi_cache, matched );
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, matched, &lock );
matched = NULL;
} else {
@ -108,6 +119,8 @@ bdb_bind(
NULL, NULL, NULL, NULL );
}
LOCK_ID_FREE(bdb->bi_dbenv, locker);
ber_bvarray_free( refs );
free( matched_dn );
@ -274,9 +287,11 @@ bdb_bind(
done:
/* free entry and reader lock */
if( e != NULL ) {
bdb_cache_return_entry_r( &bdb->bi_cache, e );
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
}
LOCK_ID_FREE(bdb->bi_dbenv, locker);
/* front end with send result on success (rc==0) */
return rc;
}

View File

@ -132,6 +132,36 @@ bdb_cache_entry_private_init( Entry *e )
return 0;
}
int
bdb_cache_entry_db_lock
( DB_ENV *env, u_int32_t locker, Entry *e, int rw, u_int32_t flags, DB_LOCK *lock )
{
int rc;
DBT lockobj;
int db_rw;
if (rw)
db_rw = DB_LOCK_WRITE;
else
db_rw = DB_LOCK_READ;
lockobj.data = e->e_nname.bv_val;
lockobj.size = e->e_nname.bv_len;
rc = LOCK_GET(env, locker, flags | DB_LOCK_NOWAIT,
&lockobj, db_rw, lock);
return rc;
}
int
bdb_cache_entry_db_unlock
( DB_ENV *env, DB_LOCK *lock )
{
int rc;
rc = LOCK_PUT ( env, lock );
return rc;
}
/*
* marks an entry in CREATING state as committed, so it is really returned
* to the cache. Otherwise an entry in CREATING state is removed.
@ -162,7 +192,110 @@ bdb_cache_entry_private_destroy( Entry *e )
}
void
bdb_cache_return_entry_rw( Cache *cache, Entry *e, int rw )
bdb_unlocked_cache_return_entry_rw( Cache *cache, Entry *e, int rw )
{
ID id;
int refcnt, freeit = 1;
/* set cache write lock */
ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
assert( e->e_private );
#if 0
bdb_cache_entry_rdwr_unlock(e, rw);
#endif
id = e->e_id;
refcnt = --BEI(e)->bei_refcnt;
/*
* if the entry is returned when in CREATING state, it is deleted
* but not freed because it may belong to someone else (do_add,
* for instance)
*/
if ( BEI(e)->bei_state == CACHE_ENTRY_CREATING ) {
/* set lru mutex */
ldap_pvt_thread_mutex_lock( &cache->lru_mutex );
bdb_cache_delete_entry_internal( cache, e );
/* free lru mutex */
ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );
freeit = 0;
/* now the entry is in DELETED state */
}
if ( BEI(e)->bei_state == CACHE_ENTRY_COMMITTED ) {
BEI(e)->bei_state = CACHE_ENTRY_READY;
/* free cache write lock */
ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
#ifdef NEW_LOGGING
LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
"bdb_cache_return_entry_rw: return (%ld):%s, refcnt=%d\n",
id, rw ? "w" : "r", refcnt ));
#else
Debug( LDAP_DEBUG_TRACE,
"====> bdb_cache_return_entry_%s( %ld ): created (%d)\n",
rw ? "w" : "r", id, refcnt );
#endif
} else if ( BEI(e)->bei_state == CACHE_ENTRY_DELETED ) {
if( refcnt > 0 ) {
/* free cache write lock */
ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
#ifdef NEW_LOGGING
LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
"bdb_cache_return_entry_rw: %ld, delete pending (%d).\n",
id, refcnt ));
#else
Debug( LDAP_DEBUG_TRACE,
"====> bdb_cache_return_entry_%s( %ld ): delete pending (%d)\n",
rw ? "w" : "r", id, refcnt );
#endif
} else {
bdb_cache_entry_private_destroy( e );
if ( freeit ) {
bdb_entry_return( e );
}
/* free cache write lock */
ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
#ifdef NEW_LOGGING
LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
"bdb_cache_return_entry_rw: (%ld): deleted (%d)\n",
id, refcnt ));
#else
Debug( LDAP_DEBUG_TRACE,
"====> bdb_cache_return_entry_%s( %ld ): deleted (%d)\n",
rw ? "w" : "r", id, refcnt );
#endif
}
} else {
/* free cache write lock */
ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
#ifdef NEW_LOGGING
LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
"bdb_cache_return_entry_rw: ID %ld:%s returned (%d)\n",
id, rw ? "w": "r", refcnt ));
#else
Debug( LDAP_DEBUG_TRACE,
"====> bdb_cache_return_entry_%s( %ld ): returned (%d)\n",
rw ? "w" : "r", id, refcnt);
#endif
}
}
void
bdb_cache_return_entry_rw
( DB_ENV *env, Cache *cache, Entry *e, int rw, DB_LOCK *lock )
{
ID id;
int refcnt, freeit = 1;
@ -172,7 +305,10 @@ bdb_cache_return_entry_rw( Cache *cache, Entry *e, int rw )
assert( e->e_private );
bdb_cache_entry_db_unlock( env, lock );
#if 0
bdb_cache_entry_rdwr_unlock(e, rw);
#endif
id = e->e_id;
refcnt = --BEI(e)->bei_refcnt;
@ -290,12 +426,16 @@ bdb_cache_return_entry_rw( Cache *cache, Entry *e, int rw )
* returns: 0 entry has been created and locked
* 1 entry already existed
* -1 something bad happened
* other Berkeley DB locking error code
*/
int
bdb_cache_add_entry_rw(
DB_ENV *env,
Cache *cache,
Entry *e,
int rw
int rw,
u_int32_t locker,
DB_LOCK *lock
)
{
int i, rc;
@ -385,7 +525,37 @@ bdb_cache_add_entry_rw(
return( -1 );
}
bdb_cache_entry_rdwr_lock( e, rw );
rc = bdb_cache_entry_db_lock( env, locker, e, rw, 0, lock );
switch ( rc ) {
case 0 :
break;
case DB_LOCK_DEADLOCK :
case DB_LOCK_NOTGRANTED :
/* undo avl changes immediately */
if ( avl_delete( &cache->c_idtree, (caddr_t) e,
(AVL_CMP) entry_id_cmp ) == NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG(( "cache", LDAP_LEVEL_INFO,
"bdb_cache_add_entry: can't delete (%s) from cache.\n", e->e_dn ));
#else
Debug( LDAP_DEBUG_ANY, "====> can't delete from id cache\n", 0, 0, 0 );
#endif
}
if ( avl_delete( &cache->c_dntree, (caddr_t) e,
(AVL_CMP) entry_dn_cmp ) == NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG(( "cache", LDAP_LEVEL_INFO,
"bdb_cache_add_entry: can't delete (%s) from cache.\n", e->e_dn ));
#else
Debug( LDAP_DEBUG_ANY, "====> can't delete from dn cache\n", 0, 0, 0 );
#endif
}
/* fall through */
default :
bdb_cache_entry_private_destroy(e);
ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
return rc;
}
/* put the entry into 'CREATING' state */
/* will be marked after when entry is returned */
@ -661,14 +831,18 @@ try_again:
Entry *
bdb_cache_find_entry_id(
DB_ENV *env,
Cache *cache,
ID id,
int rw
int rw,
u_int32_t locker,
DB_LOCK *lock
)
{
Entry e;
Entry *ep;
int count = 0;
int rc;
e.e_id = id;
@ -715,7 +889,13 @@ try_again:
}
/* acquire reader lock */
rc = bdb_cache_entry_db_lock ( env, locker, ep, rw, 0, lock );
#if 0
if ( bdb_cache_entry_rdwr_trylock(ep, rw) == LDAP_PVT_THREAD_EBUSY ) {
#endif
if ( rc ) { /* will be changed to retry beyond threshold */
/* could not acquire entry lock...
* owner cannot free as we have the cache locked.
* so, unlock the cache, yield, and try again.
@ -732,6 +912,9 @@ try_again:
Debug(LDAP_DEBUG_TRACE,
"====> bdb_cache_find_entry_id( %ld ): %ld (busy) %d\n",
id, ep_id, state);
Debug(LDAP_DEBUG_TRACE,
"locker = %d\n",
locker, 0, 0);
#endif
ldap_pvt_thread_yield();

View File

@ -31,8 +31,14 @@ bdb_compare(
const char *text = NULL;
int manageDSAit = get_manageDSAit( op );
u_int32_t locker;
DB_LOCK lock;
LOCK_ID ( bdb->bi_dbenv, &locker );
dn2entry_retry:
/* get entry */
rc = bdb_dn2entry_r( be, NULL, ndn, &e, &matched, 0 );
rc = bdb_dn2entry_r( be, NULL, ndn, &e, &matched, 0, locker, &lock );
switch( rc ) {
case DB_NOTFOUND:
@ -41,6 +47,9 @@ bdb_compare(
case LDAP_BUSY:
text = "ldap server busy";
goto return_results;
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto dn2entry_retry;
default:
rc = LDAP_OTHER;
text = "internal error";
@ -56,7 +65,7 @@ bdb_compare(
refs = is_entry_referral( matched )
? get_entry_referrals( be, conn, op, matched )
: NULL;
bdb_cache_return_entry_r( &bdb->bi_cache, matched );
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, matched, &lock );
matched = NULL;
} else {
@ -125,8 +134,10 @@ return_results:
done:
/* free entry */
if( e != NULL ) {
bdb_cache_return_entry_r( &bdb->bi_cache, e );
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
}
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
return rc;
}

View File

@ -33,6 +33,9 @@ bdb_delete(
AttributeDescription *children = slap_schema.si_ad_children;
DB_TXN *ltid = NULL;
struct bdb_op_info opinfo;
u_int32_t locker;
DB_LOCK lock;
#if 0
u_int32_t lockid;
DB_LOCK lock;
@ -49,7 +52,7 @@ bdb_delete(
if( 0 ) {
retry: /* transaction retry */
if( e != NULL ) {
bdb_cache_return_entry_w(&bdb->bi_cache, e);
bdb_cache_return_entry_w(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
}
#ifdef NEW_LOGGING
LDAP_LOG (( "delete", LDAP_LEVEL_DETAIL1,
@ -87,6 +90,8 @@ retry: /* transaction retry */
text = "internal error";
goto return_results;
}
locker = TXN_ID ( ltid );
#if 0
lockid = TXN_ID( ltid );
#endif
@ -111,7 +116,7 @@ retry: /* transaction retry */
}
#endif
/* get parent */
rc = bdb_dn2entry_r( be, ltid, &pdn, &p, NULL, 0 );
rc = bdb_dn2entry_r( be, ltid, &pdn, &p, NULL, 0, locker, &lock );
switch( rc ) {
case 0:
@ -147,7 +152,7 @@ retry: /* transaction retry */
rc = access_allowed( be, conn, op, p,
children, NULL, ACL_WRITE, NULL );
bdb_cache_return_entry_r(&bdb->bi_cache, p);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, p, &lock);
p = NULL;
switch( opinfo.boi_err ) {
@ -226,7 +231,7 @@ retry: /* transaction retry */
}
/* get entry for read/modify/write */
rc = bdb_dn2entry_w( be, ltid, ndn, &e, &matched, DB_RMW );
rc = bdb_dn2entry_w( be, ltid, ndn, &e, &matched, DB_RMW, locker, &lock );
switch( rc ) {
case 0:
@ -263,7 +268,7 @@ retry: /* transaction retry */
refs = is_entry_referral( matched )
? get_entry_referrals( be, conn, op, matched )
: NULL;
bdb_cache_return_entry_r(&bdb->bi_cache, matched );
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, matched, &lock );
matched = NULL;
} else {
@ -465,7 +470,7 @@ return_results:
done:
/* free entry */
if( e != NULL ) {
bdb_cache_return_entry_w(&bdb->bi_cache, e);
bdb_cache_return_entry_w(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
}
if( ltid != NULL ) {

View File

@ -25,7 +25,9 @@ bdb_dn2entry_rw(
Entry **e,
Entry **matched,
int flags,
int rw )
int rw,
u_int32_t locker,
DB_LOCK *lock )
{
int rc;
ID id, id2 = 0;
@ -52,9 +54,9 @@ bdb_dn2entry_rw(
}
if( id2 == 0 ) {
rc = bdb_id2entry_rw( be, tid, id, e, rw );
rc = bdb_id2entry_rw( be, tid, id, e, rw, locker, lock );
} else {
rc = bdb_id2entry_r( be, tid, id2, matched);
rc = bdb_id2entry_r( be, tid, id2, matched, locker, lock );
}
return rc;

View File

@ -44,6 +44,9 @@ bdb_group(
const char *group_oc_name = NULL;
const char *group_at_name = group_at->ad_cname.bv_val;
u_int32_t locker;
DB_LOCK lock;
if( group_oc->soc_names && group_oc->soc_names[0] ) {
group_oc_name = group_oc->soc_names[0];
} else {
@ -76,6 +79,11 @@ bdb_group(
txn = boi->boi_txn;
}
if ( txn )
locker = TXN_ID( txn );
else
LOCK_ID ( bdb->bi_dbenv, &locker );
if (dn_match(&target->e_name, gr_ndn)) {
/* we already have a LOCKED copy of the entry */
e = target;
@ -88,12 +96,18 @@ bdb_group(
gr_ndn->bv_val, 0, 0 );
#endif
} else {
dn2entry_retry:
/* can we find group entry */
rc = bdb_dn2entry_r( be, NULL, gr_ndn, &e, NULL, 0 );
rc = bdb_dn2entry_r( be, NULL, gr_ndn, &e, NULL, 0, locker, &lock );
if( rc ) {
if ( rc == DB_LOCK_DEADLOCK || rc == DB_LOCK_NOTGRANTED )
goto dn2entry_retry;
if( txn ) {
boi->boi_err = rc;
}
else {
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
}
return( 1 );
}
if (e == NULL) {
@ -106,6 +120,9 @@ bdb_group(
"=> bdb_group: cannot find group: \"%s\"\n",
gr_ndn->bv_val, 0, 0 );
#endif
if ( txn == NULL ) {
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
}
return( 1 );
}
#ifdef NEW_LOGGING
@ -211,7 +228,11 @@ bdb_group(
return_results:
if( target != e ) {
/* free entry */
bdb_cache_return_entry_r( &bdb->bi_cache, e );
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
}
if ( txn == NULL ) {
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
}
#ifdef NEW_LOGGING

View File

@ -80,13 +80,15 @@ int bdb_id2entry_rw(
DB_TXN *tid,
ID id,
Entry **e,
int rw )
int rw,
u_int32_t locker,
DB_LOCK *lock )
{
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
DB *db = bdb->bi_id2entry->bdi_db;
DBT key, data;
struct berval bv;
int rc = 0;
int rc = 0, ret = 0;
*e = NULL;
@ -97,7 +99,7 @@ int bdb_id2entry_rw(
DBTzero( &data );
data.flags = DB_DBT_MALLOC;
if ((*e = bdb_cache_find_entry_id(&bdb->bi_cache, id, rw)) != NULL) {
if ((*e = bdb_cache_find_entry_id(bdb->bi_dbenv, &bdb->bi_cache, id, rw, locker, lock)) != NULL) {
return 0;
}
@ -121,24 +123,36 @@ int bdb_id2entry_rw(
ch_free( data.data );
}
while (rc == 0 && bdb_cache_add_entry_rw(&bdb->bi_cache, *e, rw) != 0) {
Entry *ee;
int add_loop_cnt = 0;
if ( (*e)->e_private != NULL ) {
free ((*e)->e_private);
if ( rc == 0 ) {
ret = bdb_cache_add_entry_rw( bdb->bi_dbenv,
&bdb->bi_cache, *e, rw, locker, lock);
while ( ret == 1 || ret == -1 ) {
Entry *ee;
int add_loop_cnt = 0;
if ( (*e)->e_private != NULL ) {
free ((*e)->e_private);
}
(*e)->e_private = NULL;
if ( (ee = bdb_cache_find_entry_id
(bdb->bi_dbenv, &bdb->bi_cache, id, rw, locker, lock) ) != NULL) {
bdb_entry_return ( *e );
*e = ee;
return 0;
}
if ( ++add_loop_cnt == BDB_MAX_ADD_LOOP ) {
bdb_entry_return ( *e );
*e = NULL;
return LDAP_BUSY;
}
}
(*e)->e_private = NULL;
if ( (ee = bdb_cache_find_entry_id
(&bdb->bi_cache, id, rw) ) != NULL) {
bdb_entry_return ( *e );
*e = ee;
return 0;
}
if ( ++add_loop_cnt == BDB_MAX_ADD_LOOP ) {
bdb_entry_return ( *e );
if ( ret != 0 ) {
if ( (*e)->e_private != NULL )
free ( (*e)->e_private );
bdb_entry_return( *e );
*e = NULL;
return LDAP_BUSY;
ch_free( data.data );
}
rc = ret;
}
#ifdef BDB_HIER
@ -232,7 +246,7 @@ int bdb_entry_release(
if ( slapMode == SLAP_SERVER_MODE ) {
/* free entry and reader or writer lock */
bdb_cache_return_entry_rw( &bdb->bi_cache, e, rw );
bdb_unlocked_cache_return_entry_rw( &bdb->bi_cache, e, rw );
} else {
if (e->e_private != NULL)
free (e->e_private);

View File

@ -249,6 +249,9 @@ bdb_modify(
DB_TXN *ltid = NULL;
struct bdb_op_info opinfo;
u_int32_t locker;
DB_LOCK lock;
#ifdef NEW_LOGGING
LDAP_LOG (( "modify", LDAP_LEVEL_ENTRY, "bdb_modify: %s\n", dn->bv_val ));
#else
@ -259,7 +262,7 @@ bdb_modify(
retry: /* transaction retry */
if( e != NULL ) {
bdb_cache_delete_entry(&bdb->bi_cache, e);
bdb_cache_return_entry_w(&bdb->bi_cache, e);
bdb_cache_return_entry_w(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
}
#ifdef NEW_LOGGING
LDAP_LOG (( "modify", LDAP_LEVEL_DETAIL1, "bdb_modify: retrying...\n" ));
@ -295,13 +298,15 @@ retry: /* transaction retry */
goto return_results;
}
locker = TXN_ID ( ltid );
opinfo.boi_bdb = be;
opinfo.boi_txn = ltid;
opinfo.boi_err = 0;
op->o_private = &opinfo;
/* get entry */
rc = bdb_dn2entry_w( be, ltid, ndn, &e, &matched, 0 );
rc = bdb_dn2entry_w( be, ltid, ndn, &e, &matched, 0, locker, &lock );
if ( rc != 0 ) {
#ifdef NEW_LOGGING
@ -337,7 +342,7 @@ retry: /* transaction retry */
refs = is_entry_referral( matched )
? get_entry_referrals( be, conn, op, matched )
: NULL;
bdb_cache_return_entry_r (&bdb->bi_cache, matched);
bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
matched = NULL;
} else {
@ -463,7 +468,7 @@ done:
}
if( e != NULL ) {
bdb_cache_return_entry_w (&bdb->bi_cache, e);
bdb_cache_return_entry_w (bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
}
return rc;
}

View File

@ -56,6 +56,9 @@ bdb_modrdn(
int manageDSAit = get_manageDSAit( op );
u_int32_t locker;
DB_LOCK lock;
#ifdef NEW_LOGGING
LDAP_LOG (( "modrdn", LDAP_LEVEL_ENTRY, "==>bdb_modrdn(%s,%s,%s)\n",
dn->bv_val,newrdn->bv_val,
@ -78,13 +81,13 @@ bdb_modrdn(
retry: /* transaction retry */
if (e != NULL) {
bdb_cache_delete_entry(&bdb->bi_cache, e);
bdb_cache_return_entry_w(&bdb->bi_cache, e);
bdb_cache_return_entry_w(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
}
if (p != NULL) {
bdb_cache_return_entry_r(&bdb->bi_cache, p);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, p, &lock);
}
if (np != NULL) {
bdb_cache_return_entry_r(&bdb->bi_cache, np);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, np, &lock);
}
#ifdef NEW_LOGGING
LDAP_LOG (( "modrdn", LDAP_LEVEL_DETAIL1, "==>bdb_modrdn: retrying...\n"));
@ -119,13 +122,15 @@ retry: /* transaction retry */
goto return_results;
}
locker = TXN_ID ( ltid );
opinfo.boi_bdb = be;
opinfo.boi_txn = ltid;
opinfo.boi_err = 0;
op->o_private = &opinfo;
/* get entry */
rc = bdb_dn2entry_w( be, ltid, ndn, &e, &matched, 0 );
rc = bdb_dn2entry_w( be, ltid, ndn, &e, &matched, 0, locker, &lock );
switch( rc ) {
case 0:
@ -152,7 +157,7 @@ retry: /* transaction retry */
refs = is_entry_referral( matched )
? get_entry_referrals( be, conn, op, matched )
: NULL;
bdb_cache_return_entry_r( &bdb->bi_cache, matched );
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, matched, &lock );
matched = NULL;
} else {
@ -199,7 +204,7 @@ retry: /* transaction retry */
/* Make sure parent entry exist and we can write its
* children.
*/
rc = bdb_dn2entry_r( be, ltid, &p_ndn, &p, NULL, 0 );
rc = bdb_dn2entry_r( be, ltid, &p_ndn, &p, NULL, 0, locker, &lock );
switch( rc ) {
case 0:
@ -348,7 +353,7 @@ retry: /* transaction retry */
/* newSuperior == entry being moved?, if so ==> ERROR */
/* Get Entry with dn=newSuperior. Does newSuperior exist? */
rc = bdb_dn2entry_r( be, ltid, nnewSuperior, &np, NULL, 0 );
rc = bdb_dn2entry_r( be, ltid, nnewSuperior, &np, NULL, 0, locker, &lock );
switch( rc ) {
case 0:
@ -855,17 +860,17 @@ done:
/* LDAP v3 Support */
if( np != NULL ) {
/* free new parent and reader lock */
bdb_cache_return_entry_r(&bdb->bi_cache, np);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, np, &lock);
}
if( p != NULL ) {
/* free parent and reader lock */
bdb_cache_return_entry_r(&bdb->bi_cache, p);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, p, &lock);
}
/* free entry */
if( e != NULL ) {
bdb_cache_return_entry_w( &bdb->bi_cache, e );
bdb_cache_return_entry_w( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
}
if( ltid != NULL ) {

View File

@ -44,9 +44,11 @@ bdb_operational(
if( 0 ) {
retry: /* transaction retry */
#if 0
if( e != NULL ) {
bdb_cache_return_entry_w(&bdb->bi_cache, e);
bdb_cache_return_entry_w(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
}
#endif
#ifdef NEW_LOGGING
LDAP_LOG (( "operational", LDAP_LEVEL_DETAIL1,
"=> bdb_operational: retrying...\n" ));

View File

@ -41,6 +41,9 @@ bdb_exop_passwd(
struct berval dn;
struct berval ndn;
u_int32_t locker;
DB_LOCK lock;
assert( reqoid != NULL );
assert( strcmp( LDAP_EXOP_MODIFY_PASSWD, reqoid ) == 0 );
@ -109,7 +112,7 @@ bdb_exop_passwd(
retry: /* transaction retry */
if ( e != NULL ) {
bdb_cache_delete_entry(&bdb->bi_cache, e);
bdb_cache_return_entry_w(&bdb->bi_cache, e);
bdb_cache_return_entry_w(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
}
#ifdef NEW_LOGGING
LDAP_LOG (( "passwd", LDAP_LEVEL_DETAIL1, "bdb_exop_passwd: retrying...\n" ));
@ -144,13 +147,15 @@ retry: /* transaction retry */
goto done;
}
locker = TXN_ID ( ltid );
opinfo.boi_bdb = be;
opinfo.boi_txn = ltid;
opinfo.boi_err = 0;
op->o_private = &opinfo;
/* get entry */
rc = bdb_dn2entry_w( be, ltid, &ndn, &e, NULL, 0 );
rc = bdb_dn2entry_w( be, ltid, &ndn, &e, NULL, 0 , locker, &lock);
switch(rc) {
case DB_LOCK_DEADLOCK:
@ -256,7 +261,7 @@ retry: /* transaction retry */
done:
if( e != NULL ) {
bdb_cache_return_entry_w( &bdb->bi_cache, e );
bdb_cache_return_entry_w( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
}
if( hash.bv_val != NULL ) {

View File

@ -58,9 +58,9 @@ bdb_db_cache(
* dn2entry.c
*/
int bdb_dn2entry_rw LDAP_P(( BackendDB *be, DB_TXN *tid,
struct berval *dn, Entry **e, Entry **matched, int flags, int rw ));
#define bdb_dn2entry_r(be, tid, dn, e, m, f) bdb_dn2entry_rw((be), (tid), (dn), (e), (m), (f), 0)
#define bdb_dn2entry_w(be, tid, dn, e, m, f) bdb_dn2entry_rw((be), (tid), (dn), (e), (m), (f), 1)
struct berval *dn, Entry **e, Entry **matched, int flags, int rw , u_int32_t locker, DB_LOCK *lock));
#define bdb_dn2entry_r(be, tid, dn, e, m, f, locker, lock) bdb_dn2entry_rw((be), (tid), (dn), (e), (m), (f), 0, locker, lock)
#define bdb_dn2entry_w(be, tid, dn, e, m, f, locker, lock) bdb_dn2entry_rw((be), (tid), (dn), (e), (m), (f), 1, locker, lock)
/*
* dn2id.c
@ -152,9 +152,11 @@ int bdb_id2entry_rw(
DB_TXN *tid,
ID id,
Entry **e,
int rw );
#define bdb_id2entry_r(be, tid, id, e) bdb_id2entry_rw((be), (tid), (id), (e), 0)
#define bdb_id2entry_w(be, tid, id, e) bdb_id2entry_rw((be), (tid), (id), (e), 1)
int rw,
u_int32_t locker,
DB_LOCK *lock );
#define bdb_id2entry_r(be, tid, id, e, locker, lock) bdb_id2entry_rw((be), (tid), (id), (e), 0, locker, lock)
#define bdb_id2entry_w(be, tid, id, e, locker, lock) bdb_id2entry_rw((be), (tid), (id), (e), 1, locker, lock)
void bdb_entry_free ( Entry *e );
@ -301,13 +303,19 @@ BI_op_extended bdb_exop_passwd;
*/
void bdb_cache_entry_commit( Entry *e );
void bdb_cache_return_entry_rw( Cache *cache, Entry *e, int rw );
#define bdb_cache_return_entry_r(c, e) bdb_cache_return_entry_rw((c), (e), 0)
#define bdb_cache_return_entry_w(c, e) bdb_cache_return_entry_rw((c), (e), 1)
void bdb_cache_return_entry_rw( DB_ENV *env, Cache *cache, Entry *e, int rw, DB_LOCK *lock );
#define bdb_cache_return_entry_r(env, c, e, l) bdb_cache_return_entry_rw((env), (c), (e), 0, (l))
#define bdb_cache_return_entry_w(env, c, e, l) bdb_cache_return_entry_rw((env), (c), (e), 1, (l))
void bdb_unlocked_cache_return_entry_rw( Cache *cache, Entry *e, int rw );
#define bdb_unlocked_cache_return_entry_r( c, e ) bdb_cache_return_entry_rw((c), (e), 0)
#define bdb_unlocked_cache_return_entry_w( c, e ) bdb_cache_return_entry_rw((c), (e), 1)
int bdb_cache_add_entry_rw(
Cache *cache,
Entry *e,
int rw
DB_ENV *env,
Cache *cache,
Entry *e,
int rw,
u_int32_t locker,
DB_LOCK *lock
);
int bdb_cache_update_entry(
Cache *cache,
@ -319,9 +327,12 @@ ID bdb_cache_find_entry_ndn2id(
struct berval *ndn
);
Entry* bdb_cache_find_entry_id(
Cache *cache,
ID id,
int rw
DB_ENV *env,
Cache *cache,
ID id,
int rw,
u_int32_t locker,
DB_LOCK *lock
);
int bdb_cache_delete_entry(
Cache *cache,

View File

@ -26,6 +26,9 @@ bdb_referrals(
Entry *e = NULL;
Entry *matched = NULL;
u_int32_t locker;
DB_LOCK lock;
if( op->o_tag == LDAP_REQ_SEARCH ) {
/* let search take care of itself */
return rc;
@ -36,8 +39,11 @@ bdb_referrals(
return rc;
}
LOCK_ID ( bdb->bi_dbenv, &locker );
dn2entry_retry:
/* get entry */
rc = bdb_dn2entry_r( be, NULL, ndn, &e, &matched, 0 );
rc = bdb_dn2entry_r( be, NULL, ndn, &e, &matched, 0, locker, &lock );
switch(rc) {
case DB_NOTFOUND:
@ -46,14 +52,18 @@ bdb_referrals(
break;
case LDAP_BUSY:
if (e != NULL) {
bdb_cache_return_entry_r(&bdb->bi_cache, e);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
}
if (matched != NULL) {
bdb_cache_return_entry_r(&bdb->bi_cache, matched);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
}
send_ldap_result( conn, op, LDAP_BUSY,
NULL, "ldap server busy", NULL, NULL );
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
return LDAP_BUSY;
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto dn2entry_retry;
default:
#ifdef NEW_LOGGING
LDAP_LOG (( "referral", LDAP_LEVEL_ERR,
@ -65,13 +75,14 @@ bdb_referrals(
db_strerror(rc), rc, 0 );
#endif
if (e != NULL) {
bdb_cache_return_entry_r(&bdb->bi_cache, e);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
}
if (matched != NULL) {
bdb_cache_return_entry_r(&bdb->bi_cache, matched);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
}
send_ldap_result( conn, op, rc=LDAP_OTHER,
NULL, "internal error", NULL, NULL );
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
return rc;
}
@ -97,7 +108,7 @@ bdb_referrals(
refs = get_entry_referrals( be, conn, op, matched );
}
bdb_cache_return_entry_r (&bdb->bi_cache, matched);
bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
matched = NULL;
} else if ( default_referral != NULL ) {
rc = LDAP_OTHER;
@ -116,6 +127,7 @@ bdb_referrals(
NULL, NULL );
}
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
free( matched_dn );
return rc;
}
@ -148,6 +160,7 @@ bdb_referrals(
ber_bvarray_free( refs );
}
bdb_cache_return_entry_r(&bdb->bi_cache, e);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
return rc;
}

View File

@ -59,6 +59,9 @@ bdb_search(
struct slap_limits_set *limit = NULL;
int isroot = 0;
u_int32_t locker;
DB_LOCK lock;
#ifdef NEW_LOGGING
LDAP_LOG (( "search", LDAP_LEVEL_ENTRY,"bdb_back_search\n"));
#else
@ -68,6 +71,8 @@ bdb_search(
manageDSAit = get_manageDSAit( op );
LOCK_ID (bdb->bi_dbenv, &locker );
if ( nbase->bv_len == 0 ) {
/* DIT root special case */
e = (Entry *) &slap_entry_root;
@ -81,7 +86,8 @@ bdb_search(
} else
#endif
{
rc = bdb_dn2entry_r( be, NULL, nbase, &e, &matched, 0 );
dn2entry_retry:
rc = bdb_dn2entry_r( be, NULL, nbase, &e, &matched, 0, locker, &lock );
}
switch(rc) {
@ -90,23 +96,28 @@ bdb_search(
break;
case LDAP_BUSY:
if (e != NULL) {
bdb_cache_return_entry_r(&bdb->bi_cache, e);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
}
if (matched != NULL) {
bdb_cache_return_entry_r(&bdb->bi_cache, matched);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
}
send_ldap_result( conn, op, LDAP_BUSY,
NULL, "ldap server busy", NULL, NULL );
LOCK_ID_FREE (bdb->bi_dbenv, locker );
return LDAP_BUSY;
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto dn2entry_retry;
default:
if (e != NULL) {
bdb_cache_return_entry_r(&bdb->bi_cache, e);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
}
if (matched != NULL) {
bdb_cache_return_entry_r(&bdb->bi_cache, matched);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
}
send_ldap_result( conn, op, rc=LDAP_OTHER,
NULL, "internal error", NULL, NULL );
LOCK_ID_FREE (bdb->bi_dbenv, locker );
return rc;
}
@ -123,7 +134,7 @@ bdb_search(
? get_entry_referrals( be, conn, op, matched )
: NULL;
bdb_cache_return_entry_r (&bdb->bi_cache, matched);
bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
matched = NULL;
if( erefs ) {
@ -140,6 +151,7 @@ bdb_search(
send_ldap_result( conn, op, rc=LDAP_REFERRAL ,
matched_dn.bv_val, text, refs, NULL );
LOCK_ID_FREE (bdb->bi_dbenv, locker );
if ( refs ) ber_bvarray_free( refs );
if ( matched_dn.bv_val ) ber_memfree( matched_dn.bv_val );
return rc;
@ -154,7 +166,7 @@ bdb_search(
erefs = get_entry_referrals( be, conn, op, e );
refs = NULL;
bdb_cache_return_entry_r( &bdb->bi_cache, e );
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
e = NULL;
if( erefs ) {
@ -175,6 +187,7 @@ bdb_search(
refs ? NULL : "bad referral object",
refs, NULL );
LOCK_ID_FREE (bdb->bi_dbenv, locker );
ber_bvarray_free( refs );
ber_memfree( matched_dn.bv_val );
return 1;
@ -270,7 +283,7 @@ bdb_search(
cursor = e->e_id == NOID ? 1 : e->e_id;
if ( e != &slap_entry_root ) {
bdb_cache_return_entry_r(&bdb->bi_cache, e);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
}
e = NULL;
@ -320,14 +333,18 @@ bdb_search(
goto done;
}
id2entry_retry:
/* get the entry with reader lock */
rc = bdb_id2entry_r( be, NULL, id, &e );
rc = bdb_id2entry_r( be, NULL, id, &e, locker, &lock );
if (rc == LDAP_BUSY) {
send_ldap_result( conn, op, rc=LDAP_BUSY,
NULL, "ldap server busy", NULL, NULL );
goto done;
}
else if ( rc == DB_LOCK_DEADLOCK || rc == DB_LOCK_NOTGRANTED ) {
goto id2entry_retry;
}
if ( e == NULL ) {
if( !BDB_IDL_IS_RANGE(candidates) ) {
@ -456,7 +473,7 @@ bdb_search(
if ( scopeok ) {
/* check size limit */
if ( --slimit == -1 ) {
bdb_cache_return_entry_r (&bdb->bi_cache, e);
bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
e = NULL;
send_search_result( conn, op,
rc = LDAP_SIZELIMIT_EXCEEDED, NULL, NULL,
@ -481,7 +498,7 @@ bdb_search(
case 1: /* entry not sent */
break;
case -1: /* connection closed */
bdb_cache_return_entry_r(&bdb->bi_cache, e);
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
e = NULL;
rc = LDAP_OTHER;
goto done;
@ -509,7 +526,7 @@ bdb_search(
loop_continue:
if( e != NULL ) {
/* free reader lock */
bdb_cache_return_entry_r ( &bdb->bi_cache, e );
bdb_cache_return_entry_r ( bdb->bi_dbenv, &bdb->bi_cache, e , &lock);
e = NULL;
}
@ -524,9 +541,11 @@ loop_continue:
done:
if( e != NULL ) {
/* free reader lock */
bdb_cache_return_entry_r ( &bdb->bi_cache, e );
bdb_cache_return_entry_r ( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
}
LOCK_ID_FREE (bdb->bi_dbenv, locker );
if( v2refs ) ber_bvarray_free( v2refs );
if( realbase.bv_val ) ch_free( realbase.bv_val );