From: Kurt Zeilenga Date: Fri, 2 Apr 1999 19:09:59 +0000 (+0000) Subject: cache: implement try_again loop if cache entry is not ready. X-Git-Tag: OPENLDAP_SLAPD_BACK_LDAP~271 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=e46877f89f218a4acb6cfb9161b114febf73ac71;p=openldap cache: implement try_again loop if cache entry is not ready. id2entry: when an error occurs attempting to insert fetched entry into cache, check to see if entry was added by another thread. If so, return the entry added by the other thread. The concurrency tests now run without the dreaded "no such object" error messages! --- diff --git a/servers/slapd/back-bdb2/cache.c b/servers/slapd/back-bdb2/cache.c index a22085c17b..f37b870234 100644 --- a/servers/slapd/back-bdb2/cache.c +++ b/servers/slapd/back-bdb2/cache.c @@ -362,12 +362,13 @@ bdb2i_cache_find_entry_dn2id( Entry e, *ep; ID id; - /* set cache mutex */ - ldap_pvt_thread_mutex_lock( &cache->c_mutex ); - e.e_dn = dn; e.e_ndn = dn_normalize_case( ch_strdup( dn ) ); +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 ) { @@ -395,7 +396,8 @@ bdb2i_cache_find_entry_dn2id( /* free cache mutex */ ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - return( NOID ); + ldap_pvt_thread_yield(); + goto try_again; } Debug(LDAP_DEBUG_TRACE, @@ -439,6 +441,7 @@ bdb2i_cache_find_entry_id( e.e_id = id; +try_again: /* set cache mutex */ ldap_pvt_thread_mutex_lock( &cache->c_mutex ); @@ -462,7 +465,8 @@ bdb2i_cache_find_entry_id( /* free cache mutex */ ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - return( NULL ); + ldap_pvt_thread_yield(); + goto try_again; } Debug(LDAP_DEBUG_TRACE, diff --git a/servers/slapd/back-bdb2/id2entry.c b/servers/slapd/back-bdb2/id2entry.c index bbcb8be1b1..a2cc63690c 100644 --- a/servers/slapd/back-bdb2/id2entry.c +++ b/servers/slapd/back-bdb2/id2entry.c @@ -159,10 +159,19 @@ bdb2i_id2entry_rw( BackendDB *be, ID id, int rw ) } if ( bdb2i_cache_add_entry_rw( &li->li_cache, e, rw ) != 0 ) { + entry_free( e ); + + /* see if it got added underneath us */ + if((e = bdb2i_cache_find_entry_id( &li->li_cache, id, rw )) != NULL ) { + Debug( LDAP_DEBUG_TRACE, + "<= bdb2i_id2entry_%s( %ld ) 0x%lx (cache)\n", + rw ? "w" : "r", id, (unsigned long)e ); + return( e ); + } + Debug( LDAP_DEBUG_TRACE, "<= bdb2i_id2entry_%s( %ld ) (cache add failed)\n", rw ? "w" : "r", id, 0 ); - entry_free( e ); return( NULL ); } diff --git a/servers/slapd/back-ldbm/cache.c b/servers/slapd/back-ldbm/cache.c index e5bd055b51..6fb33306b6 100644 --- a/servers/slapd/back-ldbm/cache.c +++ b/servers/slapd/back-ldbm/cache.c @@ -430,12 +430,13 @@ cache_find_entry_dn2id( Entry e, *ep; ID id; - /* set cache mutex */ - ldap_pvt_thread_mutex_lock( &cache->c_mutex ); - e.e_dn = dn; e.e_ndn = dn_normalize_case( ch_strdup( dn ) ); +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 ) { @@ -462,7 +463,8 @@ cache_find_entry_dn2id( /* free cache mutex */ ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - return( NOID ); + ldap_pvt_thread_yield(); + goto try_again; } Debug(LDAP_DEBUG_TRACE, @@ -529,7 +531,8 @@ try_again: /* free cache mutex */ ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - return( NULL ); + ldap_pvt_thread_yield(); + goto try_again; } Debug(LDAP_DEBUG_TRACE, diff --git a/servers/slapd/back-ldbm/id2entry.c b/servers/slapd/back-ldbm/id2entry.c index 58de12b7c7..783fccc8b2 100644 --- a/servers/slapd/back-ldbm/id2entry.c +++ b/servers/slapd/back-ldbm/id2entry.c @@ -158,9 +158,17 @@ id2entry_rw( Backend *be, ID id, int rw ) } if( cache_add_entry_rw( &li->li_cache, e, rw ) != 0 ) { + entry_free( e ); + + /* maybe the entry got added underneath us */ + if ( (e = cache_find_entry_id( &li->li_cache, id, rw )) != NULL ) { + Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) 0x%lx (cache)\n", + rw ? "w" : "r", id, (unsigned long) e ); + return( e ); + } + Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) (cache add failed)\n", rw ? "w" : "r", id, 0 ); - entry_free( e ); return NULL; }