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_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;
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)
+ */
+void
+cache_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 int
cache_entry_private_destroy( Entry*e )
{
cache_return_entry_rw( Cache *cache, Entry *e, int rw )
{
ID id;
- int refcnt;
+ int refcnt, freeit = 1;
/* set cache mutex */
ldap_pvt_thread_mutex_lock( &cache->c_mutex );
id = e->e_id;
refcnt = --LEI(e)->lei_refcnt;
- if ( LEI(e)->lei_state == CACHE_ENTRY_CREATING ) {
+ /*
+ * 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 */
} else {
cache_entry_private_destroy( e );
- entry_free( e );
+ if ( freeit ) {
+ entry_free( e );
+ }
/* free cache mutex */
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
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 );
+}
+
+ID
+cache_find_entry_ndn2id(
+ Backend *be,
+ Cache *cache,
+ const char *ndn
+)
{
Entry e, *ep;
ID id;
int count = 0;
- e.e_dn = (char *) dn;
- e.e_ndn = ch_strdup( dn );
- (void) dn_normalize( e.e_ndn );
+ /* this function is always called with normalized DN */
+ e.e_ndn = (char *)ndn;
try_again:
/* set cache mutex */
#ifdef NEW_LOGGING
LDAP_LOG(( "cache", LDAP_LEVEL_INFO,
- "cache_find_entry_dn2id: (%s)%ld not ready: %d\n",
- dn, id, state ));
+ "cache_find_entry_dn2id: (%s) %ld not ready: %d\n",
+ ndn, id, state ));
#else
Debug(LDAP_DEBUG_TRACE,
"====> cache_find_entry_dn2id(\"%s\"): %ld (not ready) %d\n",
- dn, id, state);
+ ndn, id, state);
#endif
#ifdef NEW_LOGGING
LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
- "cache_find_entry_dn2id: (%s)%ld %d tries\n",
- dn, id, count ));
+ "cache_find_entry_dn2id: (%s): %ld %d tries\n",
+ ndn, id, count ));
#else
Debug(LDAP_DEBUG_TRACE,
"====> cache_find_entry_dn2id(\"%s\"): %ld (%d tries)\n",
- dn, id, count);
+ ndn, id, count);
#endif
id = NOID;
}
- free(e.e_ndn);
-
return( id );
}
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
#ifdef NEW_LOGGING
- LDAP_LOG(( "caceh", LDAP_LEVEL_INFO,
+ LDAP_LOG(( "cache", LDAP_LEVEL_INFO,
"cache_find_entry_id: (%ld)->%ld not ready (%d).\n",
id, ep_id, state ));