mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-12 10:54:48 +08:00
ITS#4010 fixes complaint, larger problem remains
This commit is contained in:
parent
daa7b11ff5
commit
aa897eae90
@ -124,6 +124,7 @@ typedef struct bdb_cache {
|
||||
int c_maxsize;
|
||||
int c_cursize;
|
||||
int c_eiused; /* EntryInfo's in use */
|
||||
int c_leaves; /* EntryInfo leaf nodes */
|
||||
EntryInfo c_dntree;
|
||||
EntryInfo *c_eifree; /* free list */
|
||||
Avlnode *c_idtree;
|
||||
|
@ -257,6 +257,13 @@ bdb_entryinfo_add_internal(
|
||||
} else {
|
||||
bdb->bi_cache.c_eiused++;
|
||||
ber_dupbv( &ei2->bei_nrdn, &ei->bei_nrdn );
|
||||
|
||||
/* This is a new leaf node. But if parent had no kids, then it was
|
||||
* a leaf and we would be decrementing that. So, only increment if
|
||||
* the parent already has kids.
|
||||
*/
|
||||
if ( ei->bei_parent->bei_kids || !ei->bei_parent->bei_id )
|
||||
bdb->bi_cache.c_leaves++;
|
||||
avl_insert( &ei->bei_parent->bei_kids, ei2, bdb_rdn_cmp,
|
||||
avl_dup_error );
|
||||
#ifdef BDB_HIER
|
||||
@ -387,7 +394,7 @@ hdb_cache_find_parent(
|
||||
struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
|
||||
EntryInfo ei, eip, *ei2 = NULL, *ein = NULL, *eir = NULL;
|
||||
int rc;
|
||||
int addlru = 1;
|
||||
int addlru = 0;
|
||||
|
||||
ei.bei_id = id;
|
||||
ei.bei_kids = NULL;
|
||||
@ -435,11 +442,15 @@ hdb_cache_find_parent(
|
||||
ein->bei_ckids++;
|
||||
bdb_cache_entryinfo_unlock( ein );
|
||||
}
|
||||
addlru = 0;
|
||||
|
||||
if ( !eir ) {
|
||||
addlru = 0;
|
||||
}
|
||||
}
|
||||
if ( addlru ) {
|
||||
ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_mutex );
|
||||
LRU_ADD( &bdb->bi_cache, ein );
|
||||
ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.lru_mutex );
|
||||
}
|
||||
addlru = 1;
|
||||
|
||||
/* If this is the first time, save this node
|
||||
* to be returned later.
|
||||
@ -457,6 +468,8 @@ hdb_cache_find_parent(
|
||||
ei2 = &bdb->bi_cache.c_dntree;
|
||||
}
|
||||
bdb->bi_cache.c_eiused++;
|
||||
if ( ei2 && ( ei2->bei_kids || !ei2->bei_id ))
|
||||
bdb->bi_cache.c_leaves++;
|
||||
ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
|
||||
|
||||
/* Got the parent, link in and we're done. */
|
||||
@ -555,31 +568,53 @@ bdb_cache_lru_add(
|
||||
*/
|
||||
if ( bdb_cache_entry_db_lock( bdb->bi_dbenv,
|
||||
bdb->bi_cache.c_locker, elru, 1, 1, lockp ) == 0 ) {
|
||||
int stop = 0;
|
||||
|
||||
/* If there's no entry, or this node is in
|
||||
* the process of linking into the cache,
|
||||
int stop = 0, decr = 0;
|
||||
|
||||
/* If this node is in the process of linking into the cache,
|
||||
* or this node is being deleted, skip it.
|
||||
*/
|
||||
if ( !elru->bei_e || (elru->bei_state &
|
||||
( CACHE_ENTRY_NOT_LINKED | CACHE_ENTRY_DELETED ))) {
|
||||
if ( elru->bei_state &
|
||||
( CACHE_ENTRY_NOT_LINKED | CACHE_ENTRY_DELETED )) {
|
||||
bdb_cache_entry_db_unlock( bdb->bi_dbenv, lockp );
|
||||
continue;
|
||||
}
|
||||
LRU_DELETE( &bdb->bi_cache, elru );
|
||||
elru->bei_e->e_private = NULL;
|
||||
/* Free entry for this node if it's present */
|
||||
if ( elru->bei_e ) {
|
||||
elru->bei_e->e_private = NULL;
|
||||
#ifdef SLAP_ZONE_ALLOC
|
||||
bdb_entry_return( bdb, elru->bei_e, elru->bei_zseq );
|
||||
bdb_entry_return( bdb, elru->bei_e, elru->bei_zseq );
|
||||
#else
|
||||
bdb_entry_return( elru->bei_e );
|
||||
bdb_entry_return( elru->bei_e );
|
||||
#endif
|
||||
elru->bei_e = NULL;
|
||||
elru->bei_e = NULL;
|
||||
decr = 1;
|
||||
}
|
||||
/* ITS#4010 if we're in slapcat, and this node is a leaf
|
||||
* node, free it.
|
||||
*
|
||||
* FIXME: we need to do this for slapd as well, (which is
|
||||
* why we compute bi_cache.c_leaves now) but at the moment
|
||||
* we can't because it causes unresolvable deadlocks.
|
||||
*/
|
||||
if ( slapMode & SLAP_TOOL_READONLY ) {
|
||||
if ( !elru->bei_kids ) {
|
||||
/* This does LRU_DELETE for us */
|
||||
bdb_cache_delete_internal( &bdb->bi_cache, elru, 0 );
|
||||
bdb_cache_delete_cleanup( &bdb->bi_cache, elru );
|
||||
}
|
||||
/* Leave node on LRU list for a future pass */
|
||||
} else {
|
||||
LRU_DELETE( &bdb->bi_cache, elru );
|
||||
}
|
||||
bdb_cache_entry_db_unlock( bdb->bi_dbenv, lockp );
|
||||
|
||||
ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock );
|
||||
--bdb->bi_cache.c_cursize;
|
||||
if ( decr )
|
||||
--bdb->bi_cache.c_cursize;
|
||||
if (bdb->bi_cache.c_cursize <= bdb->bi_cache.c_maxsize)
|
||||
stop = 1;
|
||||
ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
|
||||
bdb_cache_entry_db_unlock( bdb->bi_dbenv, lockp );
|
||||
if (stop) break;
|
||||
}
|
||||
}
|
||||
@ -1085,7 +1120,15 @@ bdb_cache_delete(
|
||||
|
||||
/* set lru mutex */
|
||||
ldap_pvt_thread_mutex_lock( &cache->lru_mutex );
|
||||
|
||||
/* set cache write lock */
|
||||
ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
|
||||
|
||||
rc = bdb_cache_delete_internal( cache, e->e_private, 1 );
|
||||
|
||||
/* free cache write lock */
|
||||
ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
|
||||
|
||||
/* free lru mutex */
|
||||
ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );
|
||||
|
||||
@ -1137,9 +1180,6 @@ bdb_cache_delete_internal(
|
||||
{
|
||||
int rc = 0; /* return code */
|
||||
|
||||
/* set cache write lock */
|
||||
ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
|
||||
|
||||
/* Lock the parent's kids tree */
|
||||
bdb_cache_entryinfo_lock( e->bei_parent );
|
||||
|
||||
@ -1153,27 +1193,25 @@ bdb_cache_delete_internal(
|
||||
{
|
||||
rc = -1;
|
||||
}
|
||||
if ( e->bei_parent->bei_kids )
|
||||
cache->c_leaves--;
|
||||
|
||||
/* id tree */
|
||||
if ( avl_delete( &cache->c_idtree, (caddr_t) e, bdb_id_cmp ) == NULL ) {
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
if ( rc == 0 ){
|
||||
cache->c_eiused--;
|
||||
|
||||
/* lru */
|
||||
LRU_DELETE( cache, e );
|
||||
if ( e->bei_e ) cache->c_cursize--;
|
||||
}
|
||||
|
||||
cache->c_eiused--;
|
||||
|
||||
/* lru */
|
||||
LRU_DELETE( cache, e );
|
||||
if ( e->bei_e ) cache->c_cursize--;
|
||||
|
||||
/* free cache write lock */
|
||||
ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
|
||||
bdb_cache_entryinfo_unlock( e->bei_parent );
|
||||
|
||||
return( 0 );
|
||||
return( rc );
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1212,6 +1250,7 @@ bdb_cache_release_all( Cache *cache )
|
||||
}
|
||||
cache->c_cursize = 0;
|
||||
cache->c_eiused = 0;
|
||||
cache->c_leaves = 0;
|
||||
cache->c_idtree = NULL;
|
||||
cache->c_lruhead = NULL;
|
||||
cache->c_lrutail = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user