]> git.sur5r.net Git - openldap/commitdiff
ITS#5860 more ID_NOCACHE fallout
authorHoward Chu <hyc@openldap.org>
Sat, 24 Jan 2009 00:55:44 +0000 (00:55 +0000)
committerHoward Chu <hyc@openldap.org>
Sat, 24 Jan 2009 00:55:44 +0000 (00:55 +0000)
servers/slapd/back-bdb/cache.c

index e5652b1313aa4d369744ee442ddd4bbf41cfeab1..e3fcfae9dc1955b4378056fec34212fccabcba45 100644 (file)
@@ -662,7 +662,16 @@ bdb_cache_lru_purge( struct bdb_info *bdb )
        /* Wait for the mutex; we're the only one trying to purge. */
        ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_lru_mutex );
 
-       if ( bdb->bi_cache.c_cursize <= bdb->bi_cache.c_maxsize ) {
+       /* maximum number of EntryInfo leaves to cache. In slapcat
+        * we always free all leaf nodes.
+        */
+       if ( slapMode & SLAP_TOOL_READONLY )
+               eimax = 0;
+       else
+               eimax = bdb->bi_cache.c_eimax;
+
+       if ( bdb->bi_cache.c_cursize <= bdb->bi_cache.c_maxsize &&
+               bdb->bi_cache.c_leaves <= eimax ) {
                ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex );
                bdb->bi_cache.c_purging = 0;
                return;
@@ -676,14 +685,6 @@ bdb_cache_lru_purge( struct bdb_info *bdb )
 
        count = 0;
 
-       /* maximum number of EntryInfo leaves to cache. In slapcat
-        * we always free all leaf nodes.
-        */
-       if ( slapMode & SLAP_TOOL_READONLY )
-               eimax = 0;
-       else
-               eimax = bdb->bi_cache.c_eimax;
-
        /* Look for an unused entry to remove */
        for ( elru = bdb->bi_cache.c_lruhead; elru; elru = elnext ) {
                elnext = elru->bei_lrunext;
@@ -718,7 +719,7 @@ bdb_cache_lru_purge( struct bdb_info *bdb )
                        bdb->bi_cache.c_txn, elru, 1, 1, lockp ) == 0 ) {
 
                        /* Free entry for this node if it's present */
-                       if ( elru->bei_e ) {
+                       if ( elru->bei_e && bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize ) {
                                elru->bei_e->e_private = NULL;
 #ifdef SLAP_ZONE_ALLOC
                                bdb_entry_return( bdb, elru->bei_e, elru->bei_zseq );
@@ -747,7 +748,7 @@ bdb_cache_lru_purge( struct bdb_info *bdb )
                if ( islocked )
                        bdb_cache_entryinfo_unlock( elru );
 
-               if ( (unsigned) count >= bdb->bi_cache.c_minfree ) {
+               if ( (unsigned) count >= bdb->bi_cache.c_minfree && bdb->bi_cache.c_leaves <= eimax ) {
                        ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex );
                        bdb->bi_cache.c_cursize -= count;
                        ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex );
@@ -986,16 +987,19 @@ load1:
                int purge = 0;
 
                if ( load ) {
+                       ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex );
                        if ( !( flag & ID_NOCACHE )) {
-                               ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex );
                                bdb->bi_cache.c_cursize++;
                                if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize &&
                                        !bdb->bi_cache.c_purging ) {
                                        purge = 1;
                                        bdb->bi_cache.c_purging = 1;
                                }
-                               ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex );
+                       } else if ( bdb->bi_cache.c_leaves > bdb->bi_cache.c_eimax && !bdb->bi_cache.c_purging ) {
+                               purge = 1;
+                               bdb->bi_cache.c_purging = 1;
                        }
+                       ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex );
                }
                if ( purge )
                        bdb_cache_lru_purge( bdb );