rc = env->lock_vec(env, locker, tryOnly ? DB_LOCK_NOWAIT : 0,
list, 2, NULL );
- if (rc) {
+ if (rc && !tryOnly) {
#ifdef NEW_LOGGING
LDAP_LOG( CACHE, DETAIL1,
"bdb_cache_entry_db_relock: entry %ld, rw %d, rc %d\n",
rc = LOCK_GET(env, locker, tryOnly ? DB_LOCK_NOWAIT : 0,
&lockobj, db_rw, lock);
- if (rc) {
+ if (rc && !tryOnly) {
#ifdef NEW_LOGGING
LDAP_LOG( CACHE, DETAIL1,
"bdb_cache_entry_db_lock: entry %ld, rw %d, rc %d\n",
/* We don't wrap entire read operations in txn's, but
* we need our cache entry lock and any DB page locks
* to be associated, in order for deadlock detection
- * to work properly. So we use a long-lived per-thread
- * txn for this step.
+ * to work properly. So if we need to read from the DB,
+ * we use a long-lived per-thread txn for this step.
*/
- if ( !tid ) {
+ if ( !ep && !tid ) {
rc = bdb_txn_get( op, bdb->bi_dbenv, <id );
if ( ltid )
locker2 = TXN_ID( ltid );
/* Give up original read lock, obtain write lock with
* (possibly) new locker ID.
*/
- bdb_cache_entry_db_relock( bdb->bi_dbenv, locker2,
- *eip, 1, 0, lock );
- if (!ep) {
+ if ( rc == 0 ) {
+ rc = bdb_cache_entry_db_relock( bdb->bi_dbenv, locker2,
+ *eip, 1, 0, lock );
+ }
+ if ( rc == 0 && !ep) {
rc = bdb_id2entry( op->o_bd, ltid, id, &ep );
}
if ( rc == 0 ) {
(*eip)->bei_state ^= CACHE_ENTRY_LOADING;
if ( rc == 0 ) {
/* If we succeeded, downgrade back to a readlock. */
- bdb_cache_entry_db_relock( bdb->bi_dbenv, locker,
+ rc = bdb_cache_entry_db_relock( bdb->bi_dbenv, locker,
*eip, 0, 0, lock );
} else {
/* Otherwise, release the lock. */
bdb_cache_entry_db_unlock( bdb->bi_dbenv, lock );
}
- if ( !tid ) {
+ if ( locker2 != locker ) {
/* If we're using the per-thread txn, release all
* of its page locks now.
*/
/* Shouldn't happen unless we're single-threaded */
if ( !ctx ) {
*txn = NULL;
- return -1;
+ return 0;
}
if ( ldap_pvt_thread_pool_getkey( ctx, ((char *)env)+1, &data, NULL ) ) {