Move LDBM-backend specific fields of Entry struct into a private struct.

The new e_private field can be used for any backend purpose.  In LDBM,
it's used to point th the private entry info struct.  The LDBM entry
info struct is only visible to the LDBM cache.
WARNING: This change has not be ported to other backends!  Breakage is likely.
This commit is contained in:
Kurt Zeilenga 1999-02-10 18:28:25 +00:00
parent 529caeddd0
commit 88c43a1e6e
12 changed files with 323 additions and 207 deletions

View File

@ -54,11 +54,11 @@ do_add( Connection *conn, Operation *op )
}
e = (Entry *) ch_calloc( 1, sizeof(Entry) );
/* initialize reader/writer lock */
entry_rdwr_init(e);
e->e_dn = dn;
e->e_ndn = dn_normalize_case( ch_strdup( dn ) );
e->e_private = NULL;
dn = NULL;
Debug( LDAP_DEBUG_ARGS, " do_add: ndn (%s)\n", e->e_ndn, 0, 0 );

View File

@ -23,7 +23,7 @@ ldbm_back_add(
char *pdn;
Entry *p = NULL;
int rootlock = 0;
int rc = -1;
int rc;
Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n", e->e_dn, 0, 0);
@ -121,39 +121,19 @@ ldbm_back_add(
ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
}
/* acquire required reader/writer lock */
if (entry_rdwr_lock(e, 1)) {
if( p != NULL) {
/* free parent and writer lock */
cache_return_entry_w( &li->li_cache, p );
}
if ( rootlock ) {
/* release root lock */
ldap_pvt_thread_mutex_unlock(&li->li_root_mutex);
}
Debug( LDAP_DEBUG_ANY, "add: could not lock entry\n",
0, 0, 0 );
entry_free(e);
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", "" );
return( -1 );
}
e->e_id = next_id( be );
/*
* Try to add the entry to the cache, assign it a new dnid.
* This should only fail if the entry already exists.
*/
rc = cache_add_entry_rw(&li->li_cache, e, ENTRY_STATE_CREATING, 1);
if ( cache_add_entry_lock( &li->li_cache, e, ENTRY_STATE_CREATING ) != 0 ) {
if ( rc != 0 ) {
if( p != NULL) {
/* free parent and writer lock */
cache_return_entry_w( &li->li_cache, p );
}
if ( rootlock ) {
/* release root lock */
ldap_pvt_thread_mutex_unlock(&li->li_root_mutex);
@ -161,15 +141,24 @@ ldbm_back_add(
Debug( LDAP_DEBUG_ANY, "cache_add_entry_lock failed\n", 0, 0,
0 );
/* return the id */
next_id_return( be, e->e_id );
entry_rdwr_unlock(e, 1);
/* free the entry */
entry_free( e );
if(rc > 0) {
send_ldap_result( conn, op, LDAP_ALREADY_EXISTS, "", "" );
} else {
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", "" );
}
return( -1 );
}
rc = -1;
/*
* add it to the id2children index for the parent
*/

View File

@ -79,6 +79,9 @@ struct cache {
ldap_pvt_thread_mutex_t c_mutex;
};
#define ENTRY_STATE_DELETED 1
#define ENTRY_STATE_CREATING 2
/* for the cache of open index files */
struct dbcache {
int dbc_refcnt;

View File

@ -12,6 +12,23 @@
#include "back-ldbm.h"
/* LDBM backend specific entry info -- visible only to the cache */
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 */
int lei_refcnt; /* # threads ref'ing this entry */
struct entry *lei_lrunext; /* for cache lru list */
struct entry *lei_lruprev;
};
#define LEI(e) ((struct ldbm_entry_info *) ((e)->e_private))
static int cache_delete_entry_internal(struct cache *cache, Entry *e);
#ifdef LDAP_DEBUG
static void lru_print(struct cache *cache);
@ -53,27 +70,94 @@ cache_set_state( struct cache *cache, Entry *e, int state )
/* set cache mutex */
ldap_pvt_thread_mutex_lock( &cache->c_mutex );
e->e_state = state;
LEI(e)->lei_state = state;
/* free cache mutex */
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
}
#ifdef not_used
static void
cache_return_entry( struct cache *cache, Entry *e )
static int
cache_entry_rdwr_lock(Entry *e, int rw)
{
/* set cache mutex */
ldap_pvt_thread_mutex_lock( &cache->c_mutex );
Debug( LDAP_DEBUG_ARGS, "entry_rdwr_%slock: ID: %ld\n",
rw ? "w" : "r", e->e_id, 0);
if ( --e->e_refcnt == 0 && e->e_state == ENTRY_STATE_DELETED ) {
entry_free( e );
if (rw)
return ldap_pvt_thread_rdwr_wlock(&LEI(e)->lei_rdwr);
else
return ldap_pvt_thread_rdwr_rlock(&LEI(e)->lei_rdwr);
}
/* free cache mutex */
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
static int
cache_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 int
cache_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 int
cache_entry_rdwr_init(Entry *e)
{
return ldap_pvt_thread_rdwr_init( &LEI(e)->lei_rdwr );
}
static int
cache_entry_rdwr_destroy(Entry *e)
{
return ldap_pvt_thread_rdwr_destroy( &LEI(e)->lei_rdwr );
}
static int
cache_entry_private_init( Entry*e )
{
struct ldbm_entry_info *lei;
if( e->e_private != NULL ) {
return 1;
}
e->e_private = ch_calloc(1, sizeof(struct ldbm_entry_info));
if( cache_entry_rdwr_init( e ) != 0 ) {
free( LEI(e) );
return 1;
}
return 0;
}
static int
cache_entry_private_destroy( Entry*e )
{
struct ldbm_entry_info *lei;
if( e->e_private == NULL ) {
return 1;
}
cache_entry_rdwr_destroy( e );
free( e->e_private );
e->e_private = NULL;
return 0;
}
#endif
static void
cache_return_entry_rw( struct cache *cache, Entry *e, int rw )
@ -84,9 +168,12 @@ cache_return_entry_rw( struct cache *cache, Entry *e, int rw )
/* set cache mutex */
ldap_pvt_thread_mutex_lock( &cache->c_mutex );
entry_rdwr_unlock(e, rw);
cache_entry_rdwr_unlock(e, rw);
if ( --e->e_refcnt == 0 && e->e_state == ENTRY_STATE_DELETED ) {
if ( --LEI(e)->lei_refcnt == 0 &&
LEI(e)->lei_state == ENTRY_STATE_DELETED )
{
cache_entry_private_destroy( e );
entry_free( e );
}
@ -108,41 +195,42 @@ cache_return_entry_w( struct cache *cache, Entry *e )
#define LRU_DELETE( cache, e ) { \
if ( e->e_lruprev != NULL ) { \
e->e_lruprev->e_lrunext = e->e_lrunext; \
if ( LEI(e)->lei_lruprev != NULL ) { \
LEI(LEI(e)->lei_lruprev)->lei_lrunext = LEI(e)->lei_lrunext; \
} else { \
cache->c_lruhead = e->e_lrunext; \
cache->c_lruhead = LEI(e)->lei_lrunext; \
} \
if ( e->e_lrunext != NULL ) { \
e->e_lrunext->e_lruprev = e->e_lruprev; \
if ( LEI(e)->lei_lrunext != NULL ) { \
LEI(LEI(e)->lei_lrunext)->lei_lruprev = LEI(e)->lei_lruprev; \
} else { \
cache->c_lrutail = e->e_lruprev; \
cache->c_lrutail = LEI(e)->lei_lruprev; \
} \
}
#define LRU_ADD( cache, e ) { \
e->e_lrunext = cache->c_lruhead; \
if ( e->e_lrunext != NULL ) { \
e->e_lrunext->e_lruprev = e; \
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; \
e->e_lruprev = NULL; \
LEI(e)->lei_lruprev = NULL; \
if ( cache->c_lrutail == NULL ) { \
cache->c_lrutail = e; \
} \
}
/*
* cache_create_entry_lock - create an entry in the cache, and lock it.
* 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
*/
int
cache_add_entry_lock(
cache_add_entry_rw(
struct cache *cache,
Entry *e,
int state
int state,
int rw
)
{
int i, rc;
@ -151,11 +239,134 @@ cache_add_entry_lock(
/* set cache mutex */
ldap_pvt_thread_mutex_lock( &cache->c_mutex );
if ( e->e_private != NULL ) {
Debug( LDAP_DEBUG_ANY,
"====> cache_add_entry: entry %20s id %lu already cached.\n",
e->e_dn, e->e_id, 0 );
return( -1 );
}
if( cache_entry_private_init(e) != 0 ) {
Debug( LDAP_DEBUG_ANY,
"====> cache_add_entry: entry %20s id %lu: private init failed!\n",
e->e_dn, e->e_id, 0 );
return( -1 );
}
if ( avl_insert( &cache->c_dntree, (caddr_t) e,
cache_entrydn_cmp, avl_dup_error ) != 0 )
{
Debug( LDAP_DEBUG_TRACE,
"====> cache_add_entry lock: entry %20s id %lu already in dn cache\n",
"====> cache_add_entry: entry %20s id %lu already in dn cache\n",
e->e_dn, e->e_id, 0 );
cache_entry_private_destroy(e);
/* free cache mutex */
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
return( 1 );
}
/* id tree */
if ( avl_insert( &cache->c_idtree, (caddr_t) e,
cache_entryid_cmp, avl_dup_error ) != 0 )
{
Debug( LDAP_DEBUG_ANY,
"====> entry %20s id %lu already in id cache\n",
e->e_dn, e->e_id, 0 );
/* delete from dn tree inserted above */
if ( avl_delete( &cache->c_dntree, (caddr_t) e,
cache_entrydn_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 );
LEI(e)->lei_state = state;
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 */
rc = cache_delete_entry_internal( cache, 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
*/
int
cache_update_entry(
struct cache *cache,
Entry *e
)
{
int i, rc;
Entry *ee;
/* set cache mutex */
ldap_pvt_thread_mutex_lock( &cache->c_mutex );
if ( e->e_private == NULL ) {
Debug( LDAP_DEBUG_ANY,
"====> cache_update_entry: entry %20s id %lu no private data.\n",
e->e_dn, e->e_id, 0 );
return( -1 );
}
if ( avl_insert( &cache->c_dntree, (caddr_t) e,
cache_entrydn_cmp, avl_dup_error ) != 0 )
{
Debug( LDAP_DEBUG_TRACE,
"====> cache_add_entry: entry %20s id %lu already in dn cache\n",
e->e_dn, e->e_id, 0 );
/* free cache mutex */
@ -184,9 +395,6 @@ cache_add_entry_lock(
return( -1 );
}
e->e_state = state;
e->e_refcnt = 1;
/* lru */
LRU_ADD( cache, e );
if ( ++cache->c_cursize > cache->c_maxsize ) {
@ -196,8 +404,10 @@ cache_add_entry_lock(
* first 10 on the tail of the list.
*/
i = 0;
while ( cache->c_lrutail != NULL && cache->c_lrutail->e_refcnt
!= 0 && i < 10 ) {
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 );
@ -209,15 +419,12 @@ cache_add_entry_lock(
* found at least one to delete - try to get back under
* the max cache size.
*/
while ( cache->c_lrutail != NULL && cache->c_lrutail->e_refcnt
== 0 && cache->c_cursize > cache->c_maxsize ) {
while ( cache->c_lrutail != NULL &&
LEI(cache->c_lrutail)->lei_refcnt == 0 &&
cache->c_cursize > cache->c_maxsize )
{
e = cache->c_lrutail;
/* check for active readers/writer lock */
#ifdef LDAP_DEBUG
assert(!ldap_pvt_thread_rdwr_active( &e->e_rdwr ));
#endif
/* delete from cache and lru q */
rc = cache_delete_entry_internal( cache, e );
@ -267,8 +474,8 @@ cache_find_entry_dn2id(
/*
* entry is deleted or not fully created yet
*/
if ( ep->e_state == ENTRY_STATE_DELETED ||
ep->e_state == ENTRY_STATE_CREATING )
if ( LEI(ep)->lei_state == ENTRY_STATE_DELETED ||
LEI(ep)->lei_state == ENTRY_STATE_CREATING )
{
/* free cache mutex */
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
@ -326,8 +533,8 @@ try_again:
/*
* entry is deleted or not fully created yet
*/
if ( ep->e_state == ENTRY_STATE_DELETED ||
ep->e_state == ENTRY_STATE_CREATING )
if ( LEI(ep)->lei_state == ENTRY_STATE_DELETED ||
LEI(ep)->lei_state == ENTRY_STATE_CREATING )
{
/* free cache mutex */
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
@ -335,7 +542,7 @@ try_again:
}
/* acquire reader lock */
if ( entry_rdwr_trylock(ep, rw) == LDAP_PVT_THREAD_EBUSY ) {
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.
@ -351,7 +558,7 @@ try_again:
LRU_DELETE( cache, ep );
LRU_ADD( cache, ep );
ep->e_refcnt++;
LEI(ep)->lei_refcnt++;
/* free cache mutex */
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
@ -389,11 +596,6 @@ cache_delete_entry(
/* set cache mutex */
ldap_pvt_thread_mutex_lock( &cache->c_mutex );
/* XXX check for writer lock - should also check no readers pending */
#ifdef LDAP_DEBUG
assert(ldap_pvt_thread_rdwr_writers( &e->e_rdwr ) == 1);
#endif
rc = cache_delete_entry_internal( cache, e );
/* free cache mutex */
@ -434,7 +636,7 @@ cache_delete_entry_internal(
/*
* flag entry to be freed later by a call to cache_return_entry()
*/
e->e_state = ENTRY_STATE_DELETED;
LEI(e)->lei_state = ENTRY_STATE_DELETED;
return( 0 );
}
@ -447,14 +649,14 @@ lru_print( struct cache *cache )
Entry *e;
fprintf( stderr, "LRU queue (head to tail):\n" );
for ( e = cache->c_lruhead; e != NULL; e = e->e_lrunext ) {
for ( e = cache->c_lruhead; e != NULL; e = LEI(e)->lei_lrunext ) {
fprintf( stderr, "\tdn %20s id %lu refcnt %d\n", e->e_dn,
e->e_id, e->e_refcnt );
e->e_id, LEI(e)->lei_refcnt );
}
fprintf( stderr, "LRU queue (tail to head):\n" );
for ( e = cache->c_lrutail; e != NULL; e = e->e_lruprev ) {
for ( e = cache->c_lrutail; e != NULL; e = LEI(e)->lei_lruprev ) {
fprintf( stderr, "\tdn %20s id %lu refcnt %d\n", e->e_dn,
e->e_id, e->e_refcnt );
e->e_id, LEI(e)->lei_refcnt );
}
}

View File

@ -154,7 +154,7 @@ dn2id_delete(
*/
static Entry *
dn2entry(
dn2entry_rw(
Backend *be,
char *dn,
char **matched,
@ -172,7 +172,7 @@ dn2entry(
*matched = NULL;
if ( (id = dn2id( be, dn )) != NOID &&
(e = id2entry( be, id, rw )) != NULL )
(e = id2entry_rw( be, id, rw )) != NULL )
{
return( e );
}
@ -215,7 +215,7 @@ dn2entry_r(
char **matched
)
{
return( dn2entry( be, dn, matched, 0 ) );
return( dn2entry_rw( be, dn, matched, 0 ) );
}
Entry *
@ -225,7 +225,7 @@ dn2entry_w(
char **matched
)
{
return( dn2entry( be, dn, matched, 1 ) );
return( dn2entry_rw( be, dn, matched, 1 ) );
}

View File

@ -9,6 +9,11 @@
#include "slap.h"
#include "back-ldbm.h"
/*
* This routine adds (or updates) an entry on disk.
* The cache should already be updated.
*/
int
id2entry_add( Backend *be, Entry *e )
{
@ -45,11 +50,12 @@ id2entry_add( Backend *be, Entry *e )
ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
ldbm_cache_close( be, db );
(void) cache_add_entry_lock( &li->li_cache, e, 0 );
/* XXX entry should have already been added to the cache */
/* (void) cache_add_entry_rw( &li->li_cache, e, 0 ); */
Debug( LDAP_DEBUG_TRACE, "<= id2entry_add %d\n", rc, 0, 0 );
/* XXX should entries be born locked, i.e. apply writer lock here? */
return( rc );
}
@ -64,9 +70,11 @@ id2entry_delete( Backend *be, Entry *e )
Debug(LDAP_DEBUG_TRACE, "=> id2entry_delete( %lu, \"%s\" )\n", e->e_id,
e->e_dn, 0 );
#ifdef notdef
#ifdef LDAP_DEBUG
/* check for writer lock */
assert(ldap_pvt_thread_rdwr_writers(&e->e_rdwr) == 1);
#endif
#endif
ldbm_datum_init( key );
@ -96,7 +104,7 @@ id2entry_delete( Backend *be, Entry *e )
/* XXX returns entry with reader/writer lock */
Entry *
id2entry( Backend *be, ID id, int rw )
id2entry_rw( Backend *be, ID id, int rw )
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
struct dbcache *db;
@ -145,15 +153,12 @@ id2entry( Backend *be, ID id, int rw )
return( NULL );
}
/* acquire required reader/writer lock */
if (entry_rdwr_lock(e, rw)) {
/* XXX set DELETE flag?? */
entry_free(e);
return(NULL);
}
e->e_id = id;
(void) cache_add_entry_lock( &li->li_cache, e, 0 );
if( cache_add_entry_rw( &li->li_cache, e, 0, rw ) != 0 ) {
Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) (cache add failed)\n",
rw ? "w" : "r", id, 0 );
}
Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) (disk)\n",
rw ? "w" : "r", id, 0 );
@ -163,12 +168,12 @@ id2entry( Backend *be, ID id, int rw )
Entry *
id2entry_r( Backend *be, ID id )
{
return( id2entry( be, id, 0 ) );
return( id2entry_rw( be, id, 0 ) );
}
Entry *
id2entry_w( Backend *be, ID id )
{
return( id2entry( be, id, 1 ) );
return( id2entry_rw( be, id, 1 ) );
}

View File

@ -146,7 +146,9 @@ ldbm_back_modrdn(
e->e_dn = new_dn;
e->e_ndn = new_ndn;
/* XXX
(void) cache_update_entry( &li->li_cache, e );
/*
* At some point here we need to update the attribute values in
* the entry itself that were effected by this RDN change
* (respecting the value of the deleteoldrdn parameter).

View File

@ -37,7 +37,9 @@ void attr_index_config LDAP_P(( struct ldbminfo *li, char *fname, int lineno,
void cache_set_state LDAP_P(( struct cache *cache, Entry *e, int state ));
void cache_return_entry_r LDAP_P(( struct cache *cache, Entry *e ));
void cache_return_entry_w LDAP_P(( struct cache *cache, Entry *e ));
int cache_add_entry_lock LDAP_P(( struct cache *cache, Entry *e, int state ));
int cache_add_entry_rw LDAP_P(( struct cache *cache, Entry *e,
int state, int rw ));
int cache_update_entry LDAP_P(( struct cache *cache, Entry *e ));
ID cache_find_entry_dn2id LDAP_P(( Backend *be, struct cache *cache, char *dn ));
Entry * cache_find_entry_id LDAP_P(( struct cache *cache, ID id, int rw ));
int cache_delete_entry LDAP_P(( struct cache *cache, Entry *e ));
@ -85,7 +87,7 @@ int has_children LDAP_P(( Backend *be, Entry *p ));
int id2entry_add LDAP_P(( Backend *be, Entry *e ));
int id2entry_delete LDAP_P(( Backend *be, Entry *e ));
Entry * id2entry LDAP_P(( Backend *be, ID id, int rw ));
Entry * id2entry_rw LDAP_P(( Backend *be, ID id, int rw ));
Entry * id2entry_r LDAP_P(( Backend *be, ID id ));
Entry * id2entry_w LDAP_P(( Backend *be, ID id ));

View File

@ -39,11 +39,10 @@ config_info( Connection *conn, Operation *op )
vals[1] = NULL;
e = (Entry *) ch_calloc( 1, sizeof(Entry) );
/* initialize reader/writer lock */
entry_rdwr_init(e);
e->e_attrs = NULL;
e->e_dn = ch_strdup( SLAPD_CONFIG_DN );
e->e_private = NULL;
for ( i = 0; i < nbackends; i++ ) {
strcpy( buf, backends[i].be_type );

View File

@ -68,9 +68,9 @@ str2entry( char *s )
0, 0, 0 );
return( NULL );
}
e->e_id = id;
entry_rdwr_init(e);
e->e_id = id;
e->e_private = NULL;
/* dn + attributes */
e->e_attrs = NULL;
@ -142,7 +142,8 @@ str2entry( char *s )
return( NULL );
}
Debug(LDAP_DEBUG_TRACE, "<= str2entry 0x%lx\n", (unsigned long)e, 0,0);
Debug(LDAP_DEBUG_TRACE, "<= str2entry(%s) -> %lu (0x%lx)\n",
e->e_dn, e->e_id, (unsigned long)e );
return( e );
}
@ -219,93 +220,20 @@ entry_free( Entry *e )
int i;
Attribute *a, *next;
/* check that no reader/writer locks exist */
if ( ldap_pvt_thread_rdwr_wtrylock( &e->e_rdwr ) ==
LDAP_PVT_THREAD_EBUSY )
{
Debug( LDAP_DEBUG_ANY, "entry_free(%ld): active (%d, %d)\n",
e->e_id,
ldap_pvt_thread_rdwr_readers( &e->e_rdwr ),
ldap_pvt_thread_rdwr_writers( &e->e_rdwr ));
#ifdef LDAP_DEBUG
assert(!ldap_pvt_thread_rdwr_active( &e->e_rdwr ));
#endif
}
if ( e->e_dn != NULL ) {
free( e->e_dn );
e->e_dn = NULL;
}
if ( e->e_ndn != NULL ) {
free( e->e_ndn );
e->e_ndn = NULL;
}
for ( a = e->e_attrs; a != NULL; a = next ) {
next = a->a_next;
attr_free( a );
}
e->e_attrs = NULL;
e->e_private = NULL;
free( e );
}
int
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(&e->e_rdwr);
else
return ldap_pvt_thread_rdwr_rlock(&e->e_rdwr);
}
int
entry_rdwr_rlock(Entry *e)
{
return entry_rdwr_lock( e, 0 );
}
int
entry_rdwr_wlock(Entry *e)
{
return entry_rdwr_lock( e, 1 );
}
int
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(&e->e_rdwr);
else
return ldap_pvt_thread_rdwr_rtrylock(&e->e_rdwr);
}
int
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(&e->e_rdwr);
else
return ldap_pvt_thread_rdwr_runlock(&e->e_rdwr);
}
int
entry_rdwr_runlock(Entry *e)
{
return entry_rdwr_unlock( e, 0 );
}
int
entry_rdwr_wunlock(Entry *e)
{
return entry_rdwr_unlock( e, 1 );
}
int
entry_rdwr_init(Entry *e)
{
return ldap_pvt_thread_rdwr_init( &e->e_rdwr );
}

View File

@ -46,10 +46,10 @@ monitor_info( Connection *conn, Operation *op )
e = (Entry *) ch_calloc( 1, sizeof(Entry) );
/* initialize reader/writer lock */
entry_rdwr_init(e);
e->e_attrs = NULL;
e->e_dn = ch_strdup( SLAPD_MONITOR_DN );
e->e_ndn = dn_normalize_case( ch_strdup(SLAPD_MONITOR_DN) );
e->e_private = NULL;
val.bv_val = Versionstr;
if (( p = strchr( Versionstr, '\n' )) == NULL ) {

View File

@ -138,33 +138,19 @@ typedef unsigned long ID;
* represents an entry in core
*/
typedef struct entry {
ldap_pvt_thread_rdwr_t e_rdwr; /* reader/writer lock */
char *e_dn; /* DN of this entry */
char *e_ndn; /* normalized DN of this entry */
Attribute *e_attrs; /* list of attributes + values */
/*
* The ID field should only be changed before entry is
* inserted into a cache. The ID value is backend
* specific.
*/
ID e_id; /* id of this entry - this should */
/* really be private to back-ldbm */
ID e_id;
/*
* remaining fields require backend cache lock to access
* These items are specific to the LDBM backend and should
* be hidden.
*/
char e_state; /* for the cache */
#define ENTRY_STATE_DELETED 1
#define ENTRY_STATE_CREATING 2
char *e_dn; /* DN of this entry */
char *e_ndn; /* normalized DN of this entry */
Attribute *e_attrs; /* list of attributes + values */
int e_refcnt; /* # threads ref'ing this entry */
struct entry *e_lrunext; /* for cache lru list */
struct entry *e_lruprev;
/* for use by the backend for any purpose */
void* e_private;
} Entry;
/*