From: Kurt Zeilenga Date: Wed, 10 Feb 1999 20:36:53 +0000 (+0000) Subject: Port cache add vs update bug fix from devel without new X-Git-Tag: OPENLDAP_REL_ENG_1_2_0~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eccd72e5d6cb0c1deeda009c199ed02c92c9ed54;p=thirdparty%2Fopenldap.git Port cache add vs update bug fix from devel without new cache managed entry locking. The cache managed entry locking should be imported as soon as possible. --- diff --git a/build/version b/build/version index 86658ea30a..a473fbbb52 100644 --- a/build/version +++ b/build/version @@ -1 +1 @@ -1.2.0-Engineering +1.2.0-Release diff --git a/servers/slapd/back-ldbm/add.c b/servers/slapd/back-ldbm/add.c index 052b23c6a9..cdda78edb0 100644 --- a/servers/slapd/back-ldbm/add.c +++ b/servers/slapd/back-ldbm/add.c @@ -149,7 +149,7 @@ ldbm_back_add( * This should only fail if the entry already exists. */ - if ( cache_add_entry_lock( &li->li_cache, e, ENTRY_STATE_CREATING ) != 0 ) { + if ( cache_add_entry( &li->li_cache, e, ENTRY_STATE_CREATING ) != 0 ) { if( p != NULL) { /* free parent and writer lock */ cache_return_entry_w( &li->li_cache, p ); diff --git a/servers/slapd/back-ldbm/cache.c b/servers/slapd/back-ldbm/cache.c index 46d8c655b6..8cfdeeaac0 100644 --- a/servers/slapd/back-ldbm/cache.c +++ b/servers/slapd/back-ldbm/cache.c @@ -59,22 +59,6 @@ cache_set_state( struct cache *cache, Entry *e, int state ) ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); } -#ifdef not_used -static void -cache_return_entry( struct cache *cache, Entry *e ) -{ - /* set cache mutex */ - ldap_pvt_thread_mutex_lock( &cache->c_mutex ); - - if ( --e->e_refcnt == 0 && e->e_state == ENTRY_STATE_DELETED ) { - entry_free( e ); - } - - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); -} -#endif - static void cache_return_entry_rw( struct cache *cache, Entry *e, int rw ) { @@ -133,13 +117,13 @@ cache_return_entry_w( struct cache *cache, Entry *e ) } /* - * cache_create_entry_lock - create an entry in the cache, and lock it. + * cache_create_entry - create an entry in the cache, and lock it. * returns: 0 entry has been created and locked * 1 entry already existed * -1 something bad happened */ int -cache_add_entry_lock( +cache_add_entry( struct cache *cache, Entry *e, int state @@ -230,6 +214,102 @@ cache_add_entry_lock( return( 0 ); } +/* + * cache_update_entry - update an entry in the cache + * returns: 0 entry has been created and locked + * 1 entry already existed + * -1 something bad happened + */ +int +cache_update_entry( + struct cache *cache, + Entry *e +) +{ + int i, rc; + Entry *ee; + + /* set cache mutex */ + ldap_pvt_thread_mutex_lock( &cache->c_mutex ); + + if ( avl_insert( &cache->c_dntree, (caddr_t) e, + cache_entrydn_cmp, avl_dup_error ) != 0 ) + { + Debug( LDAP_DEBUG_TRACE, + "====> cache_add_entry lock: entry %20s id %lu already in dn cache\n", + e->e_dn, e->e_id, 0 ); + + /* free cache mutex */ + ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); + return( 1 ); + } + + /* id tree */ + if ( avl_insert( &cache->c_idtree, (caddr_t) e, + cache_entryid_cmp, avl_dup_error ) != 0 ) + { + Debug( LDAP_DEBUG_ANY, + "====> entry %20s id %lu already in id cache\n", + e->e_dn, e->e_id, 0 ); + + /* delete from dn tree inserted above */ + if ( avl_delete( &cache->c_dntree, (caddr_t) e, + cache_entrydn_cmp ) == NULL ) + { + Debug( LDAP_DEBUG_ANY, "====> can't delete from dn cache\n", + 0, 0, 0 ); + } + + /* free cache mutex */ + ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); + return( -1 ); + } + + e->e_state = 0; + + /* lru */ + LRU_ADD( cache, e ); + if ( ++cache->c_cursize > cache->c_maxsize ) { + /* + * find the lru entry not currently in use and delete it. + * in case a lot of entries are in use, only look at the + * first 10 on the tail of the list. + */ + i = 0; + while ( cache->c_lrutail != NULL && cache->c_lrutail->e_refcnt + != 0 && i < 10 ) { + /* move this in-use entry to the front of the q */ + ee = cache->c_lrutail; + LRU_DELETE( cache, ee ); + LRU_ADD( cache, ee ); + i++; + } + + /* + * found at least one to delete - try to get back under + * the max cache size. + */ + while ( cache->c_lrutail != NULL && cache->c_lrutail->e_refcnt + == 0 && cache->c_cursize > cache->c_maxsize ) { + e = cache->c_lrutail; + + /* check for active readers/writer lock */ +#ifdef LDAP_DEBUG + assert(!ldap_pvt_thread_rdwr_active( &e->e_rdwr )); +#endif + + /* delete from cache and lru q */ + rc = cache_delete_entry_internal( cache, e ); + + entry_free( e ); + } + } + + /* free cache mutex */ + ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); + return( 0 ); +} + /* * cache_find_entry_dn2id - find an entry in the cache, given dn */ diff --git a/servers/slapd/back-ldbm/id2entry.c b/servers/slapd/back-ldbm/id2entry.c index ae5e18868e..115dc0a2fe 100644 --- a/servers/slapd/back-ldbm/id2entry.c +++ b/servers/slapd/back-ldbm/id2entry.c @@ -45,7 +45,6 @@ id2entry_add( Backend *be, Entry *e ) ldap_pvt_thread_mutex_unlock( &entry2str_mutex ); ldbm_cache_close( be, db ); - (void) cache_add_entry_lock( &li->li_cache, e, 0 ); Debug( LDAP_DEBUG_TRACE, "<= id2entry_add %d\n", rc, 0, 0 ); @@ -153,7 +152,7 @@ id2entry( Backend *be, ID id, int rw ) } e->e_id = id; - (void) cache_add_entry_lock( &li->li_cache, e, 0 ); + (void) cache_add_entry( &li->li_cache, e, 0 ); Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) (disk)\n", rw ? "w" : "r", id, 0 ); diff --git a/servers/slapd/back-ldbm/modrdn.c b/servers/slapd/back-ldbm/modrdn.c index cf2e9751aa..4bff9e72cf 100644 --- a/servers/slapd/back-ldbm/modrdn.c +++ b/servers/slapd/back-ldbm/modrdn.c @@ -145,6 +145,7 @@ ldbm_back_modrdn( free( e->e_ndn ); e->e_dn = new_dn; e->e_ndn = new_ndn; + (void) cache_update_entry( &li->li_cache, e ); /* XXX * At some point here we need to update the attribute values in diff --git a/servers/slapd/back-ldbm/proto-back-ldbm.h b/servers/slapd/back-ldbm/proto-back-ldbm.h index 2f6d4a11a4..603325d27d 100644 --- a/servers/slapd/back-ldbm/proto-back-ldbm.h +++ b/servers/slapd/back-ldbm/proto-back-ldbm.h @@ -35,7 +35,8 @@ void attr_index_config LDAP_P(( struct ldbminfo *li, char *fname, int lineno, void cache_set_state LDAP_P(( struct cache *cache, Entry *e, int state )); void cache_return_entry_r LDAP_P(( struct cache *cache, Entry *e )); void cache_return_entry_w LDAP_P(( struct cache *cache, Entry *e )); -int cache_add_entry_lock LDAP_P(( struct cache *cache, Entry *e, int state )); +int cache_add_entry LDAP_P(( struct cache *cache, Entry *e, int state )); +int cache_update_entry LDAP_P(( struct cache *cache, Entry *e )); ID cache_find_entry_dn2id LDAP_P(( Backend *be, struct cache *cache, char *dn )); Entry * cache_find_entry_id LDAP_P(( struct cache *cache, ID id, int rw )); int cache_delete_entry LDAP_P(( struct cache *cache, Entry *e ));