1 /* cache.c - routines to maintain an in-core cache of entries */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2003 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
17 * This work was initially developed by Pierangelo Masarati for inclusion
18 * in OpenLDAP Software.
20 /* This is an altered version */
22 * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
24 * This work has beed deveolped for the OpenLDAP Foundation
25 * in the hope that it may be useful to the Open Source community,
26 * but WITHOUT ANY WARRANTY.
28 * Permission is granted to anyone to use this software for any purpose
29 * on any computer system, and to alter it and redistribute it, subject
30 * to the following restrictions:
32 * 1. The author and SysNet s.n.c. are not responsible for the consequences
33 * of use of this software, no matter how awful, even if they arise from
36 * 2. The origin of this software must not be misrepresented, either by
37 * explicit claim or by omission. Since few users ever read sources,
38 * credits should appear in the documentation.
40 * 3. Altered versions must be plainly marked as such, and must not be
41 * misrepresented as being the original software. Since few users
42 * ever read sources, credits should appear in the documentation.
43 * SysNet s.n.c. cannot be responsible for the consequences of the
46 * 4. This notice may not be removed or altered.
55 #include "back-monitor.h"
58 * compares entries based on the dn
66 struct monitorcache *cc1 = ( struct monitorcache * )c1;
67 struct monitorcache *cc2 = ( struct monitorcache * )c2;
70 * case sensitive, because the dn MUST be normalized
72 return ber_bvcmp( &cc1->mc_ndn, &cc2->mc_ndn );
76 * checks for duplicate entries
84 struct monitorcache *cc1 = ( struct monitorcache * )c1;
85 struct monitorcache *cc2 = ( struct monitorcache * )c2;
88 * case sensitive, because the dn MUST be normalized
90 return ber_bvcmp( &cc1->mc_ndn, &cc2->mc_ndn ) == 0 ? -1 : 0;
94 * adds an entry to the cache and inits the mutex
98 struct monitorinfo *mi,
102 struct monitorcache *mc;
103 struct monitorentrypriv *mp;
106 assert( mi != NULL );
109 mp = ( struct monitorentrypriv *)e->e_private;
110 ldap_pvt_thread_mutex_init( &mp->mp_mutex );
112 mc = ( struct monitorcache * )ch_malloc( sizeof( struct monitorcache ) );
113 mc->mc_ndn = e->e_nname;
115 ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
116 rc = avl_insert( &mi->mi_cache, ( caddr_t )mc,
117 monitor_cache_cmp, monitor_cache_dup );
118 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
124 * locks the entry (no r/w)
131 struct monitorentrypriv *mp;
134 assert( e->e_private != NULL );
136 mp = ( struct monitorentrypriv * )e->e_private;
137 ldap_pvt_thread_mutex_lock( &mp->mp_mutex );
143 * gets an entry from the cache based on the normalized dn
148 struct monitorinfo *mi,
153 struct monitorcache tmp_mc, *mc;
155 assert( mi != NULL );
156 assert( ndn != NULL );
157 assert( ep != NULL );
159 tmp_mc.mc_ndn = *ndn;
160 ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
161 mc = ( struct monitorcache * )avl_find( mi->mi_cache,
162 ( caddr_t )&tmp_mc, monitor_cache_cmp );
165 /* entry is returned with mutex locked */
166 monitor_cache_lock( mc->mc_e );
167 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
173 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
180 * If the entry exists in cache, it is returned in locked status;
181 * otherwise, if the parent exists, if it may generate volatile
182 * descendants an attempt to generate the required entry is
183 * performed and, if successful, the entry is returned
186 monitor_cache_dn2entry(
193 struct monitorinfo *mi = (struct monitorinfo *)op->o_bd->be_private;
195 struct berval p_ndn = { 0L, NULL };
197 struct monitorentrypriv *mp;
199 assert( mi != NULL );
200 assert( ndn != NULL );
201 assert( ep != NULL );
202 assert( matched != NULL );
206 rc = monitor_cache_get( mi, ndn, ep );
207 if ( !rc && *ep != NULL ) {
211 /* try with parent/ancestors */
213 dnParent( ndn, &p_ndn );
216 if ( p_ndn.bv_val == NULL ) {
221 p_ndn.bv_len = ndn->bv_len
222 - ( ber_len_t ) ( p_ndn.bv_val - ndn->bv_val );
225 rc = monitor_cache_dn2entry( op, &p_ndn, &e_parent, matched );
226 if ( rc || e_parent == NULL) {
230 mp = ( struct monitorentrypriv * )e_parent->e_private;
232 if ( mp->mp_flags & MONITOR_F_VOLATILE_CH ) {
233 /* parent entry generates volatile children */
234 rc = monitor_entry_create( op, ndn, e_parent, ep );
238 monitor_cache_release( mi, e_parent );
247 * releases the lock of the entry; if it is marked as volatile, it is
251 monitor_cache_release(
252 struct monitorinfo *mi,
256 struct monitorentrypriv *mp;
258 assert( mi != NULL );
260 assert( e->e_private != NULL );
262 mp = ( struct monitorentrypriv * )e->e_private;
264 if ( mp->mp_flags & MONITOR_F_VOLATILE ) {
265 struct monitorcache *mc, tmp_mc;
267 /* volatile entries do not return to cache */
268 ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
269 tmp_mc.mc_ndn = e->e_nname;
270 mc = avl_delete( &mi->mi_cache,
271 ( caddr_t )&tmp_mc, monitor_cache_cmp );
272 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
275 ldap_pvt_thread_mutex_unlock( &mp->mp_mutex );
276 ldap_pvt_thread_mutex_destroy( &mp->mp_mutex );
284 ldap_pvt_thread_mutex_unlock( &mp->mp_mutex );