📄 cache.c
字号:
ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); return( 1 ); } /* id tree */ if ( avl_insert( &cache->c_idtree, (caddr_t) e, (AVL_CMP) entry_id_cmp, avl_dup_error ) != 0 ) { Debug( LDAP_DEBUG_ANY, "====> cache_update_entry( %ld ): \"%s\": already in id cache\n", e->e_id, e->e_dn, 0 ); /* delete from dn tree inserted above */ if ( avl_delete( &cache->c_dntree, (caddr_t) e, (AVL_CMP) entry_dn_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 ); } /* put the entry into 'CREATING' state */ /* will be marked after when entry is returned */ LEI(e)->lei_state = CACHE_ENTRY_CREATING; /* 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 && LEI(cache->c_lrutail)->lei_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 && LEI(cache->c_lrutail)->lei_refcnt == 0 && cache->c_cursize > cache->c_maxsize ) { e = cache->c_lrutail; /* delete from cache and lru q */ /* XXX do we need rc ? */ rc = cache_delete_entry_internal( cache, e ); cache_entry_private_destroy( 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 */IDcache_find_entry_dn2id( Backend *be, Cache *cache, const char *dn){ char *ndn; ID id; ndn = ch_strdup( dn ); (void) dn_normalize( ndn ); id = cache_find_entry_ndn2id( be, cache, ndn ); free( ndn ); return ( id );}IDcache_find_entry_ndn2id( Backend *be, Cache *cache, const char *ndn){ Entry e, *ep; ID id; int count = 0; /* this function is always called with normalized DN */ e.e_ndn = (char *)ndn;try_again: /* set cache mutex */ ldap_pvt_thread_mutex_lock( &cache->c_mutex ); if ( (ep = (Entry *) avl_find( cache->c_dntree, (caddr_t) &e, (AVL_CMP) entry_dn_cmp )) != NULL ) { int state; count++; /* * ep now points to an unlocked entry * we do not need to lock the entry if we only * check the state, refcnt, LRU, and id. */ assert( ep->e_private ); /* save id */ id = ep->e_id; state = LEI(ep)->lei_state; /* * entry is deleted or not fully created yet */ if ( state != CACHE_ENTRY_READY ) { assert(state != CACHE_ENTRY_UNDEFINED); /* free cache mutex */ ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); Debug(LDAP_DEBUG_TRACE, "====> cache_find_entry_dn2id(\"%s\"): %ld (not ready) %d\n", ndn, id, state); ldap_pvt_thread_yield(); goto try_again; } /* lru */ LRU_DELETE( cache, ep ); LRU_ADD( cache, ep ); /* free cache mutex */ ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); Debug(LDAP_DEBUG_TRACE, "====> cache_find_entry_dn2id(\"%s\"): %ld (%d tries)\n", ndn, id, count); } else { /* free cache mutex */ ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); id = NOID; } return( id );}/* * cache_find_entry_id - find an entry in the cache, given id */Entry *cache_find_entry_id( Cache *cache, ID id, int rw){ Entry e; Entry *ep; int count = 0; e.e_id = id;try_again: /* set cache mutex */ ldap_pvt_thread_mutex_lock( &cache->c_mutex ); if ( (ep = (Entry *) avl_find( cache->c_idtree, (caddr_t) &e, (AVL_CMP) entry_id_cmp )) != NULL ) { int state; ID ep_id; count++; assert( ep->e_private ); ep_id = ep->e_id; state = LEI(ep)->lei_state; /* * entry is deleted or not fully created yet */ if ( state != CACHE_ENTRY_READY ) { assert(state != CACHE_ENTRY_UNDEFINED); /* free cache mutex */ ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); Debug(LDAP_DEBUG_TRACE, "====> cache_find_entry_id( %ld ): %ld (not ready) %d\n", id, ep_id, state); ldap_pvt_thread_yield(); goto try_again; } /* acquire reader lock */ if ( cache_entry_rdwr_trylock(ep, rw) == LDAP_PVT_THREAD_EBUSY ) { /* could not acquire entry lock... * owner cannot free as we have the cache locked. * so, unlock the cache, yield, and try again. */ /* free cache mutex */ ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); Debug(LDAP_DEBUG_TRACE, "====> cache_find_entry_id( %ld ): %ld (busy) %d\n", id, ep_id, state); ldap_pvt_thread_yield(); goto try_again; } /* lru */ LRU_DELETE( cache, ep ); LRU_ADD( cache, ep ); LEI(ep)->lei_refcnt++; /* free cache mutex */ ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); Debug(LDAP_DEBUG_TRACE, "====> cache_find_entry_id( %ld ) \"%s\" (found) (%d tries)\n", ep_id, ep->e_dn, count); return( ep ); } /* free cache mutex */ ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); return( NULL );}/* * cache_delete_entry - delete the entry e from the cache. the caller * should have obtained e (increasing its ref count) via a call to one * of the cache_find_* routines. the caller should *not* call the * cache_return_entry() routine prior to calling cache_delete_entry(). * it performs this function. * * returns: 0 e was deleted ok * 1 e was not in the cache * -1 something bad happened */intcache_delete_entry( Cache *cache, Entry *e){ int rc; /* set cache mutex */ ldap_pvt_thread_mutex_lock( &cache->c_mutex ); assert( e->e_private ); Debug( LDAP_DEBUG_TRACE, "====> cache_delete_entry( %ld )\n", e->e_id, 0, 0 ); rc = cache_delete_entry_internal( cache, e ); /* free cache mutex */ ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); return( rc );}static intcache_delete_entry_internal( Cache *cache, Entry *e){ int rc = 0; /* return code */ /* dn tree */ if ( avl_delete( &cache->c_dntree, (caddr_t) e, (AVL_CMP) entry_dn_cmp ) == NULL ) { rc = -1; } /* id tree */ if ( avl_delete( &cache->c_idtree, (caddr_t) e, (AVL_CMP) entry_id_cmp ) == NULL ) { rc = -1; } if (rc != 0) { return rc; } /* lru */ LRU_DELETE( cache, e ); cache->c_cursize--; /* * flag entry to be freed later by a call to cache_return_entry() */ LEI(e)->lei_state = CACHE_ENTRY_DELETED; return( 0 );}voidcache_release_all( Cache *cache ){ Entry *e; int rc; /* set cache mutex */ ldap_pvt_thread_mutex_lock( &cache->c_mutex ); Debug( LDAP_DEBUG_TRACE, "====> cache_release_all\n", 0, 0, 0 ); while ( (e = cache->c_lrutail) != NULL && LEI(e)->lei_refcnt == 0 ) {#ifdef LDAP_RDWR_DEBUG assert(!ldap_pvt_thread_rdwr_active(&LEI(e)->lei_rdwr));#endif /* delete from cache and lru q */ /* XXX do we need rc ? */ rc = cache_delete_entry_internal( cache, e ); cache_entry_private_destroy( e ); entry_free( e ); } if ( cache->c_cursize ) { Debug( LDAP_DEBUG_TRACE, "Entry-cache could not be emptied\n", 0, 0, 0 ); } /* free cache mutex */ ldap_pvt_thread_mutex_unlock( &cache->c_mutex );}#ifdef LDAP_DEBUGstatic voidlru_print( Cache *cache ){ Entry *e; fprintf( stderr, "LRU queue (head to tail):\n" ); for ( e = cache->c_lruhead; e != NULL; e = LEI(e)->lei_lrunext ) { fprintf( stderr, "\tdn \"%20s\" id %ld refcnt %d\n", e->e_dn, e->e_id, LEI(e)->lei_refcnt ); } fprintf( stderr, "LRU queue (tail to head):\n" ); for ( e = cache->c_lrutail; e != NULL; e = LEI(e)->lei_lruprev ) { fprintf( stderr, "\tdn \"%20s\" id %ld refcnt %d\n", e->e_dn, e->e_id, LEI(e)->lei_refcnt ); }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -