Unify use of BDB lockers

This commit is contained in:
Howard Chu 2007-01-04 08:36:59 +00:00
parent 23a2339090
commit e48f72c1b5
9 changed files with 79 additions and 69 deletions

View file

@ -122,17 +122,16 @@ typedef struct bdb_entry_info {
/* for the in-core cache of entries */
typedef struct bdb_cache {
EntryInfo *c_eifree; /* free list */
Avlnode *c_idtree;
EntryInfo *c_lruhead; /* lru - add accessed entries here */
EntryInfo *c_lrutail; /* lru - rem lru entries from here */
EntryInfo c_dntree;
int c_maxsize;
int c_cursize;
int c_minfree;
int c_eiused; /* EntryInfo's in use */
int c_leaves; /* EntryInfo leaf nodes */
u_int32_t c_locker; /* used by lru cleaner */
EntryInfo c_dntree;
EntryInfo *c_eifree; /* free list */
Avlnode *c_idtree;
EntryInfo *c_lruhead; /* lru - add accessed entries here */
EntryInfo *c_lrutail; /* lru - rem lru entries from here */
ldap_pvt_thread_rdwr_t c_rwlock;
ldap_pvt_thread_mutex_t lru_head_mutex;
ldap_pvt_thread_mutex_t lru_tail_mutex;

View file

@ -31,7 +31,7 @@
#ifdef BDB_HIER
#define bdb_cache_lru_purge hdb_cache_lru_purge
#endif
static void bdb_cache_lru_purge( struct bdb_info *bdb );
static void bdb_cache_lru_purge( struct bdb_info *bdb, uint32_t locker );
static int bdb_cache_delete_internal(Cache *cache, EntryInfo *e, int decr);
#ifdef LDAP_DEBUG
@ -555,9 +555,9 @@ int hdb_cache_load(
#endif
static void
bdb_cache_lru_purge( struct bdb_info *bdb )
bdb_cache_lru_purge( struct bdb_info *bdb, uint32_t locker )
{
DB_LOCK lock, *lockp;
DB_LOCK lock;
EntryInfo *elru, *elnext;
int count, islocked;
@ -570,12 +570,6 @@ bdb_cache_lru_purge( struct bdb_info *bdb )
return;
}
if ( bdb->bi_cache.c_locker ) {
lockp = &lock;
} else {
lockp = NULL;
}
count = 0;
/* Look for an unused entry to remove */
for (elru = bdb->bi_cache.c_lruhead; elru; elru = elnext ) {
@ -610,8 +604,7 @@ bdb_cache_lru_purge( struct bdb_info *bdb )
/* If we can successfully writelock it, then
* the object is idle.
*/
if ( bdb_cache_entry_db_lock( bdb,
bdb->bi_cache.c_locker, elru, 1, 1, lockp ) == 0 ) {
if ( bdb_cache_entry_db_lock( bdb, locker, elru, 1, 1, &lock ) == 0 ) {
/* Free entry for this node if it's present */
if ( elru->bei_e ) {
@ -624,7 +617,7 @@ bdb_cache_lru_purge( struct bdb_info *bdb )
elru->bei_e = NULL;
count++;
}
bdb_cache_entry_db_unlock( bdb, lockp );
bdb_cache_entry_db_unlock( bdb, &lock );
/* ITS#4010 if we're in slapcat, and this node is a leaf
* node, free it.
@ -801,9 +794,6 @@ load1:
#endif
ep = NULL;
}
bdb_cache_entryinfo_lock( *eip );
(*eip)->bei_state ^= CACHE_ENTRY_LOADING;
bdb_cache_entryinfo_unlock( *eip );
if ( rc == 0 ) {
/* If we succeeded, downgrade back to a readlock. */
rc = bdb_cache_entry_db_relock( bdb, locker,
@ -812,6 +802,9 @@ load1:
/* Otherwise, release the lock. */
bdb_cache_entry_db_unlock( bdb, lock );
}
bdb_cache_entryinfo_lock( *eip );
(*eip)->bei_state ^= CACHE_ENTRY_LOADING;
bdb_cache_entryinfo_unlock( *eip );
} else if ( !(*eip)->bei_e ) {
/* Some other thread is trying to load the entry,
* wait for it to finish.
@ -862,7 +855,7 @@ load1:
ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex );
}
if ( purge )
bdb_cache_lru_purge( bdb );
bdb_cache_lru_purge( bdb, locker );
}
#ifdef SLAP_ZONE_ALLOC
@ -962,7 +955,7 @@ bdb_cache_add(
ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex );
if ( purge )
bdb_cache_lru_purge( bdb );
bdb_cache_lru_purge( bdb, locker );
return rc;
}

View file

@ -332,6 +332,7 @@ bdb_dn2id_children(
int
bdb_dn2idl(
Operation *op,
u_int32_t locker,
Entry *e,
ID *ids,
ID *stack )
@ -362,7 +363,7 @@ bdb_dn2idl(
AC_MEMCPY( &((char *)key.data)[1], e->e_nname.bv_val, key.size - 1 );
BDB_IDL_ZERO( ids );
rc = bdb_idl_fetch_key( op->o_bd, db, NULL, &key, ids, NULL, 0 );
rc = bdb_idl_fetch_key( op->o_bd, db, locker, &key, ids, NULL, 0 );
if( rc != 0 ) {
Debug( LDAP_DEBUG_TRACE,
@ -830,6 +831,7 @@ hdb_dn2id_children(
struct dn2id_cookie {
struct bdb_info *bdb;
Operation *op;
u_int32_t locker;
EntryInfo *ei;
ID *ids;
ID *tmp;
@ -1060,6 +1062,7 @@ gotit:
int
hdb_dn2idl(
Operation *op,
u_int32_t locker,
Entry *e,
ID *ids,
ID *stack )
@ -1090,6 +1093,7 @@ hdb_dn2idl(
cx.tmp = stack;
cx.buf = stack + BDB_IDL_UM_SIZE;
cx.op = op;
cx.locker = locker;
cx.need_sort = 0;
cx.depth = 0;

View file

@ -27,33 +27,39 @@
static int presence_candidates(
Operation *op,
u_int32_t locker,
AttributeDescription *desc,
ID *ids );
static int equality_candidates(
Operation *op,
u_int32_t locker,
AttributeAssertion *ava,
ID *ids,
ID *tmp );
static int inequality_candidates(
Operation *op,
u_int32_t locker,
AttributeAssertion *ava,
ID *ids,
ID *tmp,
int gtorlt );
static int approx_candidates(
Operation *op,
u_int32_t locker,
AttributeAssertion *ava,
ID *ids,
ID *tmp );
static int substring_candidates(
Operation *op,
u_int32_t locker,
SubstringsAssertion *sub,
ID *ids,
ID *tmp );
static int list_candidates(
Operation *op,
u_int32_t locker,
Filter *flist,
int ftype,
ID *ids,
@ -64,6 +70,7 @@ static int list_candidates(
static int
ext_candidates(
Operation *op,
u_int32_t locker,
MatchingRuleAssertion *mra,
ID *ids,
ID *tmp,
@ -72,6 +79,7 @@ ext_candidates(
static int
comp_candidates (
Operation *op,
u_int32_t locker,
MatchingRuleAssertion *mra,
ComponentFilter *f,
ID *ids,
@ -81,6 +89,7 @@ comp_candidates (
static int
ava_comp_candidates (
Operation *op,
u_int32_t locker,
AttributeAssertion *ava,
AttributeAliasing *aa,
ID *ids,
@ -91,6 +100,7 @@ ava_comp_candidates (
int
bdb_filter_candidates(
Operation *op,
u_int32_t locker,
Filter *f,
ID *ids,
ID *tmp,
@ -129,30 +139,30 @@ bdb_filter_candidates(
break;
case LDAP_FILTER_PRESENT:
Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n", 0, 0, 0 );
rc = presence_candidates( op, f->f_desc, ids );
rc = presence_candidates( op, locker, f->f_desc, ids );
break;
case LDAP_FILTER_EQUALITY:
Debug( LDAP_DEBUG_FILTER, "\tEQUALITY\n", 0, 0, 0 );
#ifdef LDAP_COMP_MATCH
if ( is_aliased_attribute && ( aa = is_aliased_attribute ( f->f_ava->aa_desc ) ) ) {
rc = ava_comp_candidates ( op, f->f_ava, aa, ids, tmp, stack );
rc = ava_comp_candidates ( op, locker, f->f_ava, aa, ids, tmp, stack );
}
else
#endif
{
rc = equality_candidates( op, f->f_ava, ids, tmp );
rc = equality_candidates( op, locker, f->f_ava, ids, tmp );
}
break;
case LDAP_FILTER_APPROX:
Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n", 0, 0, 0 );
rc = approx_candidates( op, f->f_ava, ids, tmp );
rc = approx_candidates( op, locker, f->f_ava, ids, tmp );
break;
case LDAP_FILTER_SUBSTRINGS:
Debug( LDAP_DEBUG_FILTER, "\tSUBSTRINGS\n", 0, 0, 0 );
rc = substring_candidates( op, f->f_sub, ids, tmp );
rc = substring_candidates( op, locker, f->f_sub, ids, tmp );
break;
case LDAP_FILTER_GE:
@ -160,9 +170,9 @@ bdb_filter_candidates(
Debug( LDAP_DEBUG_FILTER, "\tGE\n", 0, 0, 0 );
if( f->f_ava->aa_desc->ad_type->sat_ordering &&
( f->f_ava->aa_desc->ad_type->sat_ordering->smr_usage & SLAP_MR_ORDERED_INDEX ) )
rc = inequality_candidates( op, f->f_ava, ids, tmp, LDAP_FILTER_GE );
rc = inequality_candidates( op, locker, f->f_ava, ids, tmp, LDAP_FILTER_GE );
else
rc = presence_candidates( op, f->f_ava->aa_desc, ids );
rc = presence_candidates( op, locker, f->f_ava->aa_desc, ids );
break;
case LDAP_FILTER_LE:
@ -170,9 +180,9 @@ bdb_filter_candidates(
Debug( LDAP_DEBUG_FILTER, "\tLE\n", 0, 0, 0 );
if( f->f_ava->aa_desc->ad_type->sat_ordering &&
( f->f_ava->aa_desc->ad_type->sat_ordering->smr_usage & SLAP_MR_ORDERED_INDEX ) )
rc = inequality_candidates( op, f->f_ava, ids, tmp, LDAP_FILTER_LE );
rc = inequality_candidates( op, locker, f->f_ava, ids, tmp, LDAP_FILTER_LE );
else
rc = presence_candidates( op, f->f_ava->aa_desc, ids );
rc = presence_candidates( op, locker, f->f_ava->aa_desc, ids );
break;
case LDAP_FILTER_NOT:
@ -185,19 +195,19 @@ bdb_filter_candidates(
case LDAP_FILTER_AND:
Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 );
rc = list_candidates( op,
rc = list_candidates( op, locker,
f->f_and, LDAP_FILTER_AND, ids, tmp, stack );
break;
case LDAP_FILTER_OR:
Debug( LDAP_DEBUG_FILTER, "\tOR\n", 0, 0, 0 );
rc = list_candidates( op,
rc = list_candidates( op, locker,
f->f_or, LDAP_FILTER_OR, ids, tmp, stack );
break;
#ifdef LDAP_COMP_MATCH
case LDAP_FILTER_EXT:
Debug( LDAP_DEBUG_FILTER, "\tEXT\n", 0, 0, 0 );
rc = ext_candidates( op, f->f_mra, ids, tmp, stack );
rc = ext_candidates( op, locker, f->f_mra, ids, tmp, stack );
break;
#endif
default:
@ -223,6 +233,7 @@ out:
static int
comp_list_candidates(
Operation *op,
u_int32_t locker,
MatchingRuleAssertion* mra,
ComponentFilter *flist,
int ftype,
@ -241,7 +252,7 @@ comp_list_candidates(
continue;
}
BDB_IDL_ZERO( save );
rc = comp_candidates( op, mra, f, save, tmp, save+BDB_IDL_UM_SIZE );
rc = comp_candidates( op, locker, mra, f, save, tmp, save+BDB_IDL_UM_SIZE );
if ( rc != 0 ) {
if ( ftype == LDAP_COMP_FILTER_AND ) {
@ -287,6 +298,7 @@ comp_list_candidates(
static int
comp_equality_candidates (
Operation *op,
u_int32_t locker,
MatchingRuleAssertion *mra,
ComponentAssertion *ca,
ID *ids,
@ -363,7 +375,7 @@ comp_equality_candidates (
return 0;
}
for ( i= 0; keys[i].bv_val != NULL; i++ ) {
rc = bdb_key_read( op->o_bd, db, NULL, &keys[i], tmp, NULL, 0 );
rc = bdb_key_read( op->o_bd, db, locker, &keys[i], tmp, NULL, 0 );
if( rc == DB_NOTFOUND ) {
BDB_IDL_ZERO( ids );
@ -400,6 +412,7 @@ comp_equality_candidates (
static int
ava_comp_candidates (
Operation *op,
u_int32_t locker,
AttributeAssertion *ava,
AttributeAliasing *aa,
ID *ids,
@ -417,12 +430,13 @@ ava_comp_candidates (
mra.ma_desc = aa->aa_aliased_ad;
mra.ma_rule = ava->aa_desc->ad_type->sat_equality;
return comp_candidates ( op, &mra, ava->aa_cf, ids, tmp, stack );
return comp_candidates ( op, locker, &mra, ava->aa_cf, ids, tmp, stack );
}
static int
comp_candidates (
Operation *op,
u_int32_t locker,
MatchingRuleAssertion *mra,
ComponentFilter *f,
ID *ids,
@ -439,10 +453,10 @@ comp_candidates (
rc = f->cf_result;
break;
case LDAP_COMP_FILTER_AND:
rc = comp_list_candidates( op, mra, f->cf_and, LDAP_COMP_FILTER_AND, ids, tmp, stack );
rc = comp_list_candidates( op, locker, mra, f->cf_and, LDAP_COMP_FILTER_AND, ids, tmp, stack );
break;
case LDAP_COMP_FILTER_OR:
rc = comp_list_candidates( op, mra, f->cf_or, LDAP_COMP_FILTER_OR, ids, tmp, stack );
rc = comp_list_candidates( op, locker, mra, f->cf_or, LDAP_COMP_FILTER_OR, ids, tmp, stack );
break;
case LDAP_COMP_FILTER_NOT:
/* No component indexing supported for NOT filter */
@ -454,7 +468,7 @@ comp_candidates (
rc = LDAP_PROTOCOL_ERROR;
break;
case LDAP_COMP_FILTER_ITEM:
rc = comp_equality_candidates( op, mra, f->cf_ca, ids, tmp, stack );
rc = comp_equality_candidates( op, locker, mra, f->cf_ca, ids, tmp, stack );
break;
default:
{
@ -470,6 +484,7 @@ comp_candidates (
static int
ext_candidates(
Operation *op,
u_int32_t locker,
MatchingRuleAssertion *mra,
ID *ids,
ID *tmp,
@ -485,13 +500,14 @@ ext_candidates(
return 0;
}
return comp_candidates ( op, mra, mra->ma_cf, ids, tmp, stack);
return comp_candidates ( op, locker, mra, mra->ma_cf, ids, tmp, stack);
}
#endif
static int
list_candidates(
Operation *op,
u_int32_t locker,
Filter *flist,
int ftype,
ID *ids,
@ -509,7 +525,7 @@ list_candidates(
continue;
}
BDB_IDL_ZERO( save );
rc = bdb_filter_candidates( op, f, save, tmp,
rc = bdb_filter_candidates( op, locker, f, save, tmp,
save+BDB_IDL_UM_SIZE );
if ( rc != 0 ) {
@ -557,6 +573,7 @@ list_candidates(
static int
presence_candidates(
Operation *op,
u_int32_t locker,
AttributeDescription *desc,
ID *ids )
{
@ -601,7 +618,7 @@ presence_candidates(
return -1;
}
rc = bdb_key_read( op->o_bd, db, NULL, &prefix, ids, NULL, 0 );
rc = bdb_key_read( op->o_bd, db, locker, &prefix, ids, NULL, 0 );
if( rc == DB_NOTFOUND ) {
BDB_IDL_ZERO( ids );
@ -627,6 +644,7 @@ done:
static int
equality_candidates(
Operation *op,
u_int32_t locker,
AttributeAssertion *ava,
ID *ids,
ID *tmp )
@ -697,7 +715,7 @@ equality_candidates(
}
for ( i= 0; keys[i].bv_val != NULL; i++ ) {
rc = bdb_key_read( op->o_bd, db, NULL, &keys[i], tmp, NULL, 0 );
rc = bdb_key_read( op->o_bd, db, locker, &keys[i], tmp, NULL, 0 );
if( rc == DB_NOTFOUND ) {
BDB_IDL_ZERO( ids );
@ -743,6 +761,7 @@ equality_candidates(
static int
approx_candidates(
Operation *op,
u_int32_t locker,
AttributeAssertion *ava,
ID *ids,
ID *tmp )
@ -818,7 +837,7 @@ approx_candidates(
}
for ( i= 0; keys[i].bv_val != NULL; i++ ) {
rc = bdb_key_read( op->o_bd, db, NULL, &keys[i], tmp, NULL, 0 );
rc = bdb_key_read( op->o_bd, db, locker, &keys[i], tmp, NULL, 0 );
if( rc == DB_NOTFOUND ) {
BDB_IDL_ZERO( ids );
@ -862,6 +881,7 @@ approx_candidates(
static int
substring_candidates(
Operation *op,
u_int32_t locker,
SubstringsAssertion *sub,
ID *ids,
ID *tmp )
@ -933,7 +953,7 @@ substring_candidates(
}
for ( i= 0; keys[i].bv_val != NULL; i++ ) {
rc = bdb_key_read( op->o_bd, db, NULL, &keys[i], tmp, NULL, 0 );
rc = bdb_key_read( op->o_bd, db, locker, &keys[i], tmp, NULL, 0 );
if( rc == DB_NOTFOUND ) {
BDB_IDL_ZERO( ids );
@ -977,6 +997,7 @@ substring_candidates(
static int
inequality_candidates(
Operation *op,
u_int32_t locker,
AttributeAssertion *ava,
ID *ids,
ID *tmp,
@ -1049,7 +1070,7 @@ inequality_candidates(
BDB_IDL_ZERO( ids );
while(1) {
rc = bdb_key_read( op->o_bd, db, NULL, &keys[0], tmp, &cursor, gtorlt );
rc = bdb_key_read( op->o_bd, db, locker, &keys[0], tmp, &cursor, gtorlt );
if( rc == DB_NOTFOUND ) {
rc = 0;

View file

@ -480,7 +480,7 @@ int
bdb_idl_fetch_key(
BackendDB *be,
DB *db,
DB_TXN *tid,
u_int32_t locker,
DBT *key,
ID *ids,
DBC **saved_cursor,
@ -553,12 +553,13 @@ bdb_idl_fetch_key(
/* If we're not reusing an existing cursor, get a new one */
if( opflag != DB_NEXT ) {
rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );
rc = db->cursor( db, NULL, &cursor, bdb->bi_db_opflags );
if( rc != 0 ) {
Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "
"cursor failed: %s (%d)\n", db_strerror(rc), rc, 0 );
return rc;
}
cursor->locker = locker;
} else {
cursor = *saved_cursor;
}

View file

@ -423,10 +423,6 @@ bdb_db_open( BackendDB *be )
goto fail;
}
if ( !quick ) {
XLOCK_ID(bdb->bi_dbenv, &bdb->bi_cache.c_locker);
}
/* monitor setup */
rc = bdb_monitor_db_open( be );
if ( rc != 0 ) {
@ -490,12 +486,6 @@ bdb_db_close( BackendDB *be )
/* close db environment */
if( bdb->bi_dbenv ) {
/* Free cache locker if we enabled locking */
if ( !( slapMode & SLAP_TOOL_QUICK )) {
XLOCK_ID_FREE(bdb->bi_dbenv, bdb->bi_cache.c_locker);
bdb->bi_cache.c_locker = 0;
}
/* force a checkpoint, but not if we were ReadOnly,
* and not in Quick mode since there are no transactions there.
*/

View file

@ -30,7 +30,7 @@ int
bdb_key_read(
Backend *be,
DB *db,
DB_TXN *txn,
u_int32_t locker,
struct berval *k,
ID *ids,
DBC **saved_cursor,
@ -47,7 +47,7 @@ bdb_key_read(
key.ulen = key.size;
key.flags = DB_DBT_USERMEM;
rc = bdb_idl_fetch_key( be, db, txn, &key, ids, saved_cursor, get_flag );
rc = bdb_idl_fetch_key( be, db, locker, &key, ids, saved_cursor, get_flag );
if( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "<= bdb_index_read: failed (%d)\n",

View file

@ -120,6 +120,7 @@ int bdb_dn2id_children(
int bdb_dn2idl(
Operation *op,
u_int32_t locker,
Entry *e,
ID *ids,
ID *stack );
@ -166,6 +167,7 @@ char *ebcdic_dberror( int rc );
int bdb_filter_candidates(
Operation *op,
u_int32_t locker,
Filter *f,
ID *ids,
ID *tmp,
@ -282,7 +284,7 @@ unsigned bdb_idl_search( ID *ids, ID id );
int bdb_idl_fetch_key(
BackendDB *be,
DB *db,
DB_TXN *tid,
u_int32_t locker,
DBT *key,
ID *ids,
DBC **saved_cursor,
@ -388,7 +390,7 @@ extern int
bdb_key_read(
Backend *be,
DB *db,
DB_TXN *txn,
u_int32_t locker,
struct berval *k,
ID *ids,
DBC **saved_cursor,

View file

@ -184,7 +184,7 @@ static int search_aliases(
/* Find all aliases in database */
BDB_IDL_ZERO( aliases );
rs->sr_err = bdb_filter_candidates( op, &af, aliases,
rs->sr_err = bdb_filter_candidates( op, locker, &af, aliases,
curscop, visited );
if (rs->sr_err != LDAP_SUCCESS) {
return rs->sr_err;
@ -206,7 +206,7 @@ static int search_aliases(
* to the cumulative list of candidates.
*/
BDB_IDL_CPY( curscop, aliases );
rs->sr_err = bdb_dn2idl( op, e, subscop,
rs->sr_err = bdb_dn2idl( op, locker, e, subscop,
subscop2+BDB_IDL_DB_SIZE );
if (first) {
first = 0;
@ -1100,11 +1100,11 @@ static int search_candidates(
if( op->ors_deref & LDAP_DEREF_SEARCHING ) {
rc = search_aliases( op, rs, e, locker, ids, scopes, stack );
} else {
rc = bdb_dn2idl( op, e, ids, stack );
rc = bdb_dn2idl( op, locker, e, ids, stack );
}
if ( rc == LDAP_SUCCESS ) {
rc = bdb_filter_candidates( op, &f, ids,
rc = bdb_filter_candidates( op, locker, &f, ids,
stack, stack+BDB_IDL_UM_SIZE );
}