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

📄 cache.c

📁 开放源码的ldap系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/* cache.c - routines to maintain an in-core cache of entries *//* $OpenLDAP: pkg/ldap/servers/slapd/back-ldbm/cache.c,v 1.36.2.4 2001/07/22 02:28:29 kurt Exp $ *//* * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */#include "portable.h"#include <stdio.h>#include <ac/errno.h>#include <ac/string.h>#include <ac/socket.h>#include "slap.h"#include "back-ldbm.h"/* LDBM backend specific entry info -- visible only to the cache */typedef struct ldbm_entry_info {	ldap_pvt_thread_rdwr_t	lei_rdwr;	/* reader/writer lock */	/*	 * remaining fields require backend cache lock to access	 * These items are specific to the LDBM backend and should	 * be hidden.	 */	int		lei_state;	/* for the cache */#define	CACHE_ENTRY_UNDEFINED	0#define CACHE_ENTRY_CREATING	1#define CACHE_ENTRY_READY	2#define CACHE_ENTRY_DELETED	3#define CACHE_ENTRY_COMMITTED	4		int		lei_refcnt;	/* # threads ref'ing this entry */	Entry	*lei_lrunext;	/* for cache lru list */	Entry	*lei_lruprev;} EntryInfo;#undef LEI#define LEI(e)	((EntryInfo *) ((e)->e_private))static int	cache_delete_entry_internal(Cache *cache, Entry *e);#ifdef LDAP_DEBUGstatic void	lru_print(Cache *cache);#endifstatic intcache_entry_rdwr_lock(Entry *e, int rw){	Debug( LDAP_DEBUG_ARGS, "entry_rdwr_%slock: ID: %ld\n",		rw ? "w" : "r", e->e_id, 0);	if (rw)		return ldap_pvt_thread_rdwr_wlock(&LEI(e)->lei_rdwr);	else		return ldap_pvt_thread_rdwr_rlock(&LEI(e)->lei_rdwr);}static intcache_entry_rdwr_trylock(Entry *e, int rw){	Debug( LDAP_DEBUG_ARGS, "entry_rdwr_%strylock: ID: %ld\n",		rw ? "w" : "r", e->e_id, 0);	if (rw)		return ldap_pvt_thread_rdwr_wtrylock(&LEI(e)->lei_rdwr);	else		return ldap_pvt_thread_rdwr_rtrylock(&LEI(e)->lei_rdwr);}static intcache_entry_rdwr_unlock(Entry *e, int rw){	Debug( LDAP_DEBUG_ARGS, "entry_rdwr_%sunlock: ID: %ld\n",		rw ? "w" : "r", e->e_id, 0);	if (rw)		return ldap_pvt_thread_rdwr_wunlock(&LEI(e)->lei_rdwr);	else		return ldap_pvt_thread_rdwr_runlock(&LEI(e)->lei_rdwr);}static intcache_entry_rdwr_init(Entry *e){	return ldap_pvt_thread_rdwr_init( &LEI(e)->lei_rdwr );}static intcache_entry_rdwr_destroy(Entry *e){	return ldap_pvt_thread_rdwr_destroy( &LEI(e)->lei_rdwr );}static intcache_entry_private_init( Entry*e ){	assert( e->e_private == NULL );	if( e->e_private != NULL ) {		/* this should never happen */		return 1;	}	e->e_private = ch_calloc(1, sizeof(struct ldbm_entry_info));	if( cache_entry_rdwr_init( e ) != 0 ) {		free( LEI(e) );		e->e_private = NULL;		return 1;	} 	return 0;}/* * marks an entry in CREATING state as committed, so it is really returned * to the cache. Otherwise an entry in CREATING state is removed. * Makes e_private be destroyed at the following cache_return_entry_w, * but lets the entry untouched (owned by someone else) */voidcache_entry_commit( Entry *e ){	assert( e );	assert( e->e_private );	assert( LEI(e)->lei_state == CACHE_ENTRY_CREATING );	/* assert( LEI(e)->lei_refcnt == 1 ); */	LEI(e)->lei_state = CACHE_ENTRY_COMMITTED;}static intcache_entry_private_destroy( Entry*e ){	assert( e->e_private );	cache_entry_rdwr_destroy( e );	free( e->e_private );	e->e_private = NULL;	return 0;}voidcache_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 );	assert( e->e_private );	cache_entry_rdwr_unlock(e, rw);	id = e->e_id;	refcnt = --LEI(e)->lei_refcnt;	/*	 * if the entry is returned when in CREATING state, it is deleted	 * but not freed because it may belong to someone else (do_add,	 * for instance)	 */	if (  LEI(e)->lei_state == CACHE_ENTRY_CREATING ) {		cache_delete_entry_internal( cache, e );		freeit = 0;		/* now the entry is in DELETED state */	}	if ( LEI(e)->lei_state == CACHE_ENTRY_COMMITTED ) {		LEI(e)->lei_state = CACHE_ENTRY_READY;		/* free cache mutex */		ldap_pvt_thread_mutex_unlock( &cache->c_mutex );		Debug( LDAP_DEBUG_TRACE,			"====> cache_return_entry_%s( %ld ): created (%d)\n",			rw ? "w" : "r", id, refcnt );	} else if ( LEI(e)->lei_state == CACHE_ENTRY_DELETED ) {		if( refcnt > 0 ) {			/* free cache mutex */			ldap_pvt_thread_mutex_unlock( &cache->c_mutex );			Debug( LDAP_DEBUG_TRACE,				"====> cache_return_entry_%s( %ld ): delete pending (%d)\n",				rw ? "w" : "r", id, refcnt );		} else {			cache_entry_private_destroy( e );			if ( freeit ) {				entry_free( e );			}			/* free cache mutex */			ldap_pvt_thread_mutex_unlock( &cache->c_mutex );			Debug( LDAP_DEBUG_TRACE,				"====> cache_return_entry_%s( %ld ): deleted (%d)\n",				rw ? "w" : "r", id, refcnt );		}	} else {		/* free cache mutex */		ldap_pvt_thread_mutex_unlock( &cache->c_mutex );		Debug( LDAP_DEBUG_TRACE,			"====> cache_return_entry_%s( %ld ): returned (%d)\n",			rw ? "w" : "r", id, refcnt);	}}#define LRU_DELETE( cache, e ) do { \	if ( LEI(e)->lei_lruprev != NULL ) { \		LEI(LEI(e)->lei_lruprev)->lei_lrunext = LEI(e)->lei_lrunext; \	} else { \		(cache)->c_lruhead = LEI(e)->lei_lrunext; \	} \	if ( LEI(e)->lei_lrunext != NULL ) { \		LEI(LEI(e)->lei_lrunext)->lei_lruprev = LEI(e)->lei_lruprev; \	} else { \		(cache)->c_lrutail = LEI(e)->lei_lruprev; \	} \} while(0)#define LRU_ADD( cache, e ) do { \	LEI(e)->lei_lrunext = (cache)->c_lruhead; \	if ( LEI(e)->lei_lrunext != NULL ) { \		LEI(LEI(e)->lei_lrunext)->lei_lruprev = (e); \	} \	(cache)->c_lruhead = (e); \	LEI(e)->lei_lruprev = NULL; \	if ( (cache)->c_lrutail == NULL ) { \		(cache)->c_lrutail = (e); \	} \} while(0)/* * cache_add_entry_rw - create and lock an entry in the cache * returns:	0	entry has been created and locked *		1	entry already existed *		-1	something bad happened */intcache_add_entry_rw(    Cache	*cache,    Entry		*e,	int		rw){	int	i, rc;	Entry	*ee;	/* set cache mutex */	ldap_pvt_thread_mutex_lock( &cache->c_mutex );	assert( e->e_private == NULL );	if( cache_entry_private_init(e) != 0 ) {		/* free cache mutex */		ldap_pvt_thread_mutex_unlock( &cache->c_mutex );		Debug( LDAP_DEBUG_ANY,			"====> cache_add_entry( %ld ): \"%s\": private init failed!\n",		    e->e_id, e->e_dn, 0 );		return( -1 );	}	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 );		Debug( LDAP_DEBUG_TRACE,			"====> cache_add_entry( %ld ): \"%s\": already in dn cache\n",		    e->e_id, e->e_dn, 0 );		cache_entry_private_destroy(e);		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_add_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 );		}		cache_entry_private_destroy(e);		/* free cache mutex */		ldap_pvt_thread_mutex_unlock( &cache->c_mutex );		return( -1 );	}	cache_entry_rdwr_lock( e, rw );	/* put the entry into 'CREATING' state */	/* will be marked after when entry is returned */	LEI(e)->lei_state = CACHE_ENTRY_CREATING;	LEI(e)->lei_refcnt = 1;	/* 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_update_entry - update a LOCKED entry which has been deleted. * returns:	0	entry has been created and locked *		1	entry already existed *		-1	something bad happened */intcache_update_entry(    Cache	*cache,    Entry		*e){	int	i, rc;	Entry	*ee;	/* set cache mutex */	ldap_pvt_thread_mutex_lock( &cache->c_mutex );	assert( e->e_private );	if ( avl_insert( &cache->c_dntree, (caddr_t) e,		(AVL_CMP) entry_dn_cmp, avl_dup_error ) != 0 )	{		Debug( LDAP_DEBUG_TRACE,			"====> cache_update_entry( %ld ): \"%s\": already in dn cache\n",		    e->e_id, e->e_dn, 0 );		/* free cache mutex */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -