1 /* cache.c - routines to maintain an in-core cache of entries */
3 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
7 * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
9 * This work has beed deveolped for the OpenLDAP Foundation
10 * in the hope that it may be useful to the Open Source community,
11 * but WITHOUT ANY WARRANTY.
13 * Permission is granted to anyone to use this software for any purpose
14 * on any computer system, and to alter it and redistribute it, subject
15 * to the following restrictions:
17 * 1. The author and SysNet s.n.c. are not responsible for the consequences
18 * of use of this software, no matter how awful, even if they arise from
21 * 2. The origin of this software must not be misrepresented, either by
22 * explicit claim or by omission. Since few users ever read sources,
23 * credits should appear in the documentation.
25 * 3. Altered versions must be plainly marked as such, and must not be
26 * misrepresented as being the original software. Since few users
27 * ever read sources, credits should appear in the documentation.
28 * SysNet s.n.c. cannot be responsible for the consequences of the
31 * 4. This notice may not be removed or altered.
40 #include "back-monitor.h"
43 * compares entries based on the dn
51 struct monitorcache *cc1 = ( struct monitorcache * )c1;
52 struct monitorcache *cc2 = ( struct monitorcache * )c2;
55 * case sensitive, because the dn MUST be normalized
57 return ber_bvcmp( &cc1->mc_ndn, &cc2->mc_ndn );
61 * checks for duplicate entries
69 struct monitorcache *cc1 = ( struct monitorcache * )c1;
70 struct monitorcache *cc2 = ( struct monitorcache * )c2;
73 * case sensitive, because the dn MUST be normalized
75 return ber_bvcmp( &cc1->mc_ndn, &cc2->mc_ndn ) == 0 ? -1 : 0;
79 * adds an entry to the cache and inits the mutex
83 struct monitorinfo *mi,
87 struct monitorcache *mc;
88 struct monitorentrypriv *mp;
94 mp = ( struct monitorentrypriv *)e->e_private;
95 ldap_pvt_thread_mutex_init( &mp->mp_mutex );
97 mc = ( struct monitorcache * )ch_malloc( sizeof( struct monitorcache ) );
98 mc->mc_ndn = e->e_nname;
100 ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
101 rc = avl_insert( &mi->mi_cache, ( caddr_t )mc,
102 monitor_cache_cmp, monitor_cache_dup );
103 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
109 * locks the entry (no r/w)
116 struct monitorentrypriv *mp;
119 assert( e->e_private != NULL );
121 mp = ( struct monitorentrypriv * )e->e_private;
122 ldap_pvt_thread_mutex_lock( &mp->mp_mutex );
128 * gets an entry from the cache based on the normalized dn
133 struct monitorinfo *mi,
138 struct monitorcache tmp_mc, *mc;
140 assert( mi != NULL );
141 assert( ndn != NULL );
142 assert( ep != NULL );
144 tmp_mc.mc_ndn = *ndn;
145 ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
146 mc = ( struct monitorcache * )avl_find( mi->mi_cache,
147 ( caddr_t )&tmp_mc, monitor_cache_cmp );
150 /* entry is returned with mutex locked */
151 monitor_cache_lock( mc->mc_e );
152 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
158 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
165 * If the entry exists in cache, it is returned in locked status;
166 * otherwise, if the parent exists, if it may generate volatile
167 * descendants an attempt to generate the required entry is
168 * performed and, if successful, the entry is returned
171 monitor_cache_dn2entry(
172 struct monitorinfo *mi,
180 struct berval p_ndn = { 0L, NULL };
182 struct monitorentrypriv *mp;
184 assert( mi != NULL );
185 assert( ndn != NULL );
186 assert( ep != NULL );
187 assert( matched != NULL );
191 rc = monitor_cache_get( mi, ndn, ep );
192 if ( !rc && *ep != NULL ) {
196 /* try with parent/ancestors */
198 dnParent( ndn, &p_ndn );
201 if ( p_ndn.bv_val == NULL ) {
206 p_ndn.bv_len = ndn->bv_len
207 - ( ber_len_t ) ( p_ndn.bv_val - ndn->bv_val );
210 rc = monitor_cache_dn2entry( mi, &p_ndn, &e_parent, matched );
211 if ( rc || e_parent == NULL) {
215 mp = ( struct monitorentrypriv * )e_parent->e_private;
217 if ( mp->mp_flags & MONITOR_F_VOLATILE_CH ) {
218 /* parent entry generates volatile children */
219 rc = monitor_entry_create( mi, ndn, e_parent, ep );
223 monitor_cache_release( mi, e_parent );
232 * releases the lock of the entry; if it is marked as volatile, it is
236 monitor_cache_release(
237 struct monitorinfo *mi,
241 struct monitorentrypriv *mp;
243 assert( mi != NULL );
245 assert( e->e_private != NULL );
247 mp = ( struct monitorentrypriv * )e->e_private;
249 if ( mp->mp_flags & MONITOR_F_VOLATILE ) {
250 struct monitorcache *mc, tmp_mc;
252 /* volatile entries do not return to cache */
253 ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
254 tmp_mc.mc_ndn = e->e_nname;
255 mc = avl_delete( &mi->mi_cache,
256 ( caddr_t )&tmp_mc, monitor_cache_cmp );
257 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
260 ldap_pvt_thread_mutex_unlock( &mp->mp_mutex );
261 ldap_pvt_thread_mutex_destroy( &mp->mp_mutex );
269 ldap_pvt_thread_mutex_unlock( &mp->mp_mutex );