⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cache.c

📁 开放源码的ldap系统
💻 C
📖 第 1 页 / 共 2 页
字号:
		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 + -