]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-bdb/cache.c
Hallvard B. Furuseth's patch for cache lock and mutex
[openldap] / servers / slapd / back-bdb / cache.c
index e850a34e407a0b4eb3485da25a98b6877d898016..5038db4bc799bacf7dbe6f7982e621f379a1a0db 100644 (file)
@@ -23,7 +23,7 @@ typedef struct bdb_entry_info {
 
        /*
         * remaining fields require backend cache lock to access
-        * These items are specific to the LDBM backend and should
+        * These items are specific to the BDB backend and should
         * be hidden.
         */
        int             bei_state;      /* for the cache */
@@ -42,7 +42,7 @@ typedef struct bdb_entry_info {
 
 static int     bdb_cache_delete_entry_internal(Cache *cache, Entry *e);
 #ifdef LDAP_DEBUG
-static void    lru_print(Cache *cache);
+static void    bdb_lru_print(Cache *cache);
 #endif
 
 static int
@@ -75,7 +75,6 @@ bdb_cache_entry_rdwr_trylock(Entry *e, int rw)
                rw ? "w" : "r", e->e_id, 0);
 #endif
 
-
        if (rw)
                return ldap_pvt_thread_rdwr_wtrylock(&BEI(e)->bei_rdwr);
        else
@@ -94,7 +93,6 @@ bdb_cache_entry_rdwr_unlock(Entry *e, int rw)
                rw ? "w" : "r", e->e_id, 0);
 #endif
 
-
        if (rw)
                return ldap_pvt_thread_rdwr_wunlock(&BEI(e)->bei_rdwr);
        else
@@ -169,8 +167,8 @@ bdb_cache_return_entry_rw( Cache *cache, Entry *e, int rw )
        ID id;
        int refcnt, freeit = 1;
 
-       /* set cache mutex */
-       ldap_pvt_thread_mutex_lock( &cache->c_mutex );
+       /* set cache write lock */
+       ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
 
        assert( e->e_private );
 
@@ -185,7 +183,11 @@ bdb_cache_return_entry_rw( Cache *cache, Entry *e, int rw )
         * for instance)
         */
        if (  BEI(e)->bei_state == CACHE_ENTRY_CREATING ) {
+               /* set lru mutex */
+               ldap_pvt_thread_mutex_lock( &cache->lru_mutex );
                bdb_cache_delete_entry_internal( cache, e );
+               /* free lru mutex */
+               ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );
                freeit = 0;
                /* now the entry is in DELETED state */
        }
@@ -193,8 +195,8 @@ bdb_cache_return_entry_rw( Cache *cache, Entry *e, int rw )
        if ( BEI(e)->bei_state == CACHE_ENTRY_COMMITTED ) {
                BEI(e)->bei_state = CACHE_ENTRY_READY;
 
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+               /* free cache write lock */
+               ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
 
 #ifdef NEW_LOGGING
                LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
@@ -209,8 +211,8 @@ bdb_cache_return_entry_rw( Cache *cache, Entry *e, int rw )
 
        } else if ( BEI(e)->bei_state == CACHE_ENTRY_DELETED ) {
                if( refcnt > 0 ) {
-                       /* free cache mutex */
-                       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+                       /* free cache write lock */
+                       ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
 
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
@@ -222,15 +224,14 @@ bdb_cache_return_entry_rw( Cache *cache, Entry *e, int rw )
                                rw ? "w" : "r", id, refcnt );
 #endif
 
-
                } else {
                        bdb_cache_entry_private_destroy( e );
                        if ( freeit ) {
                                bdb_entry_return( e );
                        }
 
-                       /* free cache mutex */
-                       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+                       /* free cache write lock */
+                       ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
 
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
@@ -241,12 +242,11 @@ bdb_cache_return_entry_rw( Cache *cache, Entry *e, int rw )
                                "====> bdb_cache_return_entry_%s( %ld ): deleted (%d)\n",
                                rw ? "w" : "r", id, refcnt );
 #endif
-
                }
 
        } else {
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+               /* free cache write lock */
+               ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
 
 #ifdef NEW_LOGGING
                LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
@@ -257,7 +257,6 @@ bdb_cache_return_entry_rw( Cache *cache, Entry *e, int rw )
                        "====> bdb_cache_return_entry_%s( %ld ): returned (%d)\n",
                        rw ? "w" : "r", id, refcnt);
 #endif
-
        }
 }
 
@@ -307,14 +306,14 @@ bdb_cache_add_entry_rw(
                   "bdb_cache_add_entry_rw: add (%s):%s to cache\n",
                   e->e_dn, rw ? "w" : "r" ));
 #endif
-       /* set cache mutex */
-       ldap_pvt_thread_mutex_lock( &cache->c_mutex );
+       /* set cache write lock */
+       ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
 
        assert( e->e_private == NULL );
 
        if( bdb_cache_entry_private_init(e) != 0 ) {
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+               /* free cache write lock */
+               ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
 
 #ifdef NEW_LOGGING
                LDAP_LOG(( "cache", LDAP_LEVEL_ERR,
@@ -333,8 +332,8 @@ bdb_cache_add_entry_rw(
        if ( avl_insert( &cache->c_dntree, (caddr_t) e,
                (AVL_CMP) entry_dn_cmp, avl_dup_error ) != 0 )
        {
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+               /* free cache write lock */
+               ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
 
 #ifdef NEW_LOGGING
                LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
@@ -346,7 +345,6 @@ bdb_cache_add_entry_rw(
                    e->e_id, e->e_dn, 0 );
 #endif
 
-
                bdb_cache_entry_private_destroy(e);
 
                return( 1 );
@@ -366,8 +364,6 @@ bdb_cache_add_entry_rw(
                    e->e_id, e->e_dn, 0 );
 #endif
 
-
-
                /* delete from dn tree inserted above */
                if ( avl_delete( &cache->c_dntree, (caddr_t) e,
                        (AVL_CMP) entry_dn_cmp ) == NULL )
@@ -380,13 +376,12 @@ bdb_cache_add_entry_rw(
                        Debug( LDAP_DEBUG_ANY, "====> can't delete from dn cache\n",
                            0, 0, 0 );
 #endif
-
                }
 
                bdb_cache_entry_private_destroy(e);
 
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+               /* free cache write lock */
+               ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
                return( -1 );
        }
 
@@ -397,6 +392,8 @@ bdb_cache_add_entry_rw(
        BEI(e)->bei_state = CACHE_ENTRY_CREATING;
        BEI(e)->bei_refcnt = 1;
 
+       /* set lru mutex */
+       ldap_pvt_thread_mutex_lock( &cache->lru_mutex );
        /* lru */
        LRU_ADD( cache, e );
        if ( ++cache->c_cursize > cache->c_maxsize ) {
@@ -435,8 +432,10 @@ bdb_cache_add_entry_rw(
                }
        }
 
-       /* free cache mutex */
-       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+       /* free lru mutex */
+       ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );
+       /* free cache write lock */
+       ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
        return( 0 );
 }
 
@@ -455,8 +454,8 @@ bdb_cache_update_entry(
        int     i, rc;
        Entry   *ee;
 
-       /* set cache mutex */
-       ldap_pvt_thread_mutex_lock( &cache->c_mutex );
+       /* set cache write lock */
+       ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
 
        assert( e->e_private );
 
@@ -473,9 +472,8 @@ bdb_cache_update_entry(
                    e->e_id, e->e_dn, 0 );
 #endif
 
-
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+               /* free cache write lock */
+               ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
                return( 1 );
        }
 
@@ -493,7 +491,6 @@ bdb_cache_update_entry(
                    e->e_id, e->e_dn, 0 );
 #endif
 
-
                /* delete from dn tree inserted above */
                if ( avl_delete( &cache->c_dntree, (caddr_t) e,
                        (AVL_CMP) entry_dn_cmp ) == NULL )
@@ -506,11 +503,10 @@ bdb_cache_update_entry(
                        Debug( LDAP_DEBUG_ANY, "====> can't delete from dn cache\n",
                            0, 0, 0 );
 #endif
-
                }
 
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+               /* free cache write lock */
+               ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
                return( -1 );
        }
 
@@ -519,6 +515,8 @@ bdb_cache_update_entry(
        /* will be marked after when entry is returned */
        BEI(e)->bei_state = CACHE_ENTRY_CREATING;
 
+       /* set lru mutex */
+       ldap_pvt_thread_mutex_lock( &cache->lru_mutex );
        /* lru */
        LRU_ADD( cache, e );
        if ( ++cache->c_cursize > cache->c_maxsize ) {
@@ -557,8 +555,10 @@ bdb_cache_update_entry(
                }
        }
 
-       /* free cache mutex */
-       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+       /* free lru mutex */
+       ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );
+       /* free cache write lock */
+       ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
        return( 0 );
 }
 
@@ -577,8 +577,8 @@ bdb_cache_find_entry_ndn2id(
        e.e_nname = *ndn;
 
 try_again:
-       /* set cache mutex */
-       ldap_pvt_thread_mutex_lock( &cache->c_mutex );
+       /* set cache read lock */
+       ldap_pvt_thread_rdwr_rlock( &cache->c_rwlock );
 
        if ( (ep = (Entry *) avl_find( cache->c_dntree, (caddr_t) &e,
                (AVL_CMP) entry_dn_cmp )) != NULL )
@@ -604,8 +604,8 @@ try_again:
                if ( state != CACHE_ENTRY_READY ) {
                        assert(state != CACHE_ENTRY_UNDEFINED);
 
-                       /* free cache mutex */
-                       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+                       /* free cache read lock */
+                       ldap_pvt_thread_rdwr_runlock( &cache->c_rwlock );
 
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "cache", LDAP_LEVEL_INFO,
@@ -622,12 +622,18 @@ try_again:
                        goto try_again;
                }
 
+               /* free cache read lock */
+               ldap_pvt_thread_rdwr_runlock( &cache->c_rwlock );
+
+               /* set lru mutex */
+               ldap_pvt_thread_mutex_lock( &cache->lru_mutex );
+
                /* lru */
                LRU_DELETE( cache, ep );
                LRU_ADD( cache, ep );
                
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+               /* free lru mutex */
+               ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );
 
 #ifdef NEW_LOGGING
                LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
@@ -639,10 +645,9 @@ try_again:
                        ndn->bv_val, id, count);
 #endif
 
-
        } else {
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+               /* free cache read lock */
+               ldap_pvt_thread_rdwr_runlock( &cache->c_rwlock );
 
                id = NOID;
        }
@@ -668,8 +673,8 @@ bdb_cache_find_entry_id(
        e.e_id = id;
 
 try_again:
-       /* set cache mutex */
-       ldap_pvt_thread_mutex_lock( &cache->c_mutex );
+       /* set cache read lock */
+       ldap_pvt_thread_rdwr_rlock( &cache->c_rwlock );
 
        if ( (ep = (Entry *) avl_find( cache->c_idtree, (caddr_t) &e,
                (AVL_CMP) entry_id_cmp )) != NULL )
@@ -691,8 +696,8 @@ try_again:
 
                        assert(state != CACHE_ENTRY_UNDEFINED);
 
-                       /* free cache mutex */
-                       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+                       /* free cache read lock */
+                       ldap_pvt_thread_rdwr_runlock( &cache->c_rwlock );
 
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "cache", LDAP_LEVEL_INFO,
@@ -705,7 +710,6 @@ try_again:
                                id, ep_id, state);
 #endif
 
-
                        ldap_pvt_thread_yield();
                        goto try_again;
                }
@@ -717,8 +721,8 @@ try_again:
                         * so, unlock the cache, yield, and try again.
                         */
 
-                       /* free cache mutex */
-                       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+                       /* free cache read lock */
+                       ldap_pvt_thread_rdwr_runlock( &cache->c_rwlock );
 
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "cache", LDAP_LEVEL_INFO,
@@ -730,19 +734,22 @@ try_again:
                                id, ep_id, state);
 #endif
 
-
                        ldap_pvt_thread_yield();
                        goto try_again;
                }
 
+               /* free cache read lock */
+               ldap_pvt_thread_rdwr_runlock( &cache->c_rwlock );
+               /* set lru mutex */
+               ldap_pvt_thread_mutex_lock( &cache->lru_mutex );
                /* lru */
                LRU_DELETE( cache, ep );
                LRU_ADD( cache, ep );
                
                BEI(ep)->bei_refcnt++;
 
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+               /* free lru mutex */
+               ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );
 
 #ifdef NEW_LOGGING
                LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
@@ -758,8 +765,8 @@ try_again:
                return( ep );
        }
 
-       /* free cache mutex */
-       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+       /* free cache read lock */
+       ldap_pvt_thread_rdwr_runlock( &cache->c_rwlock );
 
        return( NULL );
 }
@@ -783,8 +790,8 @@ bdb_cache_delete_entry(
 {
        int     rc;
 
-       /* set cache mutex */
-       ldap_pvt_thread_mutex_lock( &cache->c_mutex );
+       /* set cache write lock */
+       ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
 
        assert( e->e_private );
 
@@ -796,11 +803,14 @@ bdb_cache_delete_entry(
                e->e_id, 0, 0 );
 #endif
 
-
+       /* set lru mutex */
+       ldap_pvt_thread_mutex_lock( &cache->lru_mutex );
        rc = bdb_cache_delete_entry_internal( cache, e );
+       /* free lru mutex */
+       ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );
 
-       /* free cache mutex */
-       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+       /* free cache write lock */
+       ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
        return( rc );
 }
 
@@ -848,8 +858,10 @@ bdb_cache_release_all( Cache *cache )
        Entry *e;
        int rc;
 
-       /* set cache mutex */
-       ldap_pvt_thread_mutex_lock( &cache->c_mutex );
+       /* set cache write lock */
+       ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
+       /* set lru mutex */
+       ldap_pvt_thread_mutex_lock( &cache->lru_mutex );
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "cache", LDAP_LEVEL_ENTRY,
@@ -858,7 +870,6 @@ bdb_cache_release_all( Cache *cache )
        Debug( LDAP_DEBUG_TRACE, "====> bdb_cache_release_all\n", 0, 0, 0 );
 #endif
 
-
        while ( (e = cache->c_lrutail) != NULL && BEI(e)->bei_refcnt == 0 ) {
 #ifdef LDAP_RDWR_DEBUG
                assert(!ldap_pvt_thread_rdwr_active(&BEI(e)->bei_rdwr));
@@ -881,12 +892,13 @@ bdb_cache_release_all( Cache *cache )
 
        }
 
-       /* free cache mutex */
-       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
+       /* free lru mutex */
+       ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );
+       /* free cache write lock */
+       ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
 }
 
 #ifdef LDAP_DEBUG
-
 static void
 bdb_lru_print( Cache *cache )
 {
@@ -903,5 +915,4 @@ bdb_lru_print( Cache *cache )
                        e->e_dn, e->e_id, BEI(e)->bei_refcnt );
        }
 }
-
 #endif