]> git.sur5r.net Git - openldap/commitdiff
fix some unclean unlock issues; fix potential leaks
authorPierangelo Masarati <ando@openldap.org>
Sun, 17 Jul 2005 22:19:20 +0000 (22:19 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sun, 17 Jul 2005 22:19:20 +0000 (22:19 +0000)
servers/slapd/back-monitor/cache.c
servers/slapd/back-monitor/search.c

index 8a48d9efae0d32abeb4ee030954c3ccb087fabf2..086a8337132f1e61de5c51b195d7f7450be8deed 100644 (file)
@@ -44,9 +44,8 @@ typedef struct monitor_cache_t {
  */
 int
 monitor_cache_cmp(
-               const void      *c1,
-               const void      *c2
-)
+       const void      *c1,
+       const void      *c2 )
 {
        monitor_cache_t         *cc1 = ( monitor_cache_t * )c1;
        monitor_cache_t         *cc2 = ( monitor_cache_t * )c2;
@@ -62,9 +61,8 @@ monitor_cache_cmp(
  */
 int
 monitor_cache_dup(
-               void            *c1,
-               void            *c2
-)
+       void            *c1,
+       void            *c2 )
 {
        monitor_cache_t *cc1 = ( monitor_cache_t * )c1;
        monitor_cache_t *cc2 = ( monitor_cache_t * )c2;
@@ -80,9 +78,8 @@ monitor_cache_dup(
  */
 int
 monitor_cache_add(
-               monitor_info_t  *mi,
-               Entry           *e
-)
+       monitor_info_t  *mi,
+       Entry           *e )
 {
        monitor_cache_t *mc;
        monitor_entry_t *mp;
@@ -110,18 +107,17 @@ monitor_cache_add(
  */
 int
 monitor_cache_lock(
-               Entry           *e
-)
+       Entry           *e )
 {
-               monitor_entry_t *mp;
+       monitor_entry_t *mp;
 
-               assert( e != NULL );
-               assert( e->e_private != NULL );
+       assert( e != NULL );
+       assert( e->e_private != NULL );
 
-               mp = ( monitor_entry_t * )e->e_private;
-               ldap_pvt_thread_mutex_lock( &mp->mp_mutex );
+       mp = ( monitor_entry_t * )e->e_private;
+       ldap_pvt_thread_mutex_lock( &mp->mp_mutex );
 
-               return( 0 );
+       return( 0 );
 }
 
 /*
@@ -130,10 +126,9 @@ monitor_cache_lock(
  */
 int
 monitor_cache_get(
-               monitor_info_t  *mi,
-               struct berval   *ndn,
-               Entry           **ep
-)
+       monitor_info_t  *mi,
+       struct berval   *ndn,
+       Entry           **ep )
 {
        monitor_cache_t tmp_mc, *mc;
 
@@ -169,12 +164,11 @@ monitor_cache_get(
  */
 int
 monitor_cache_dn2entry(
-               Operation               *op,
-               SlapReply               *rs,
-               struct berval           *ndn,
-               Entry                   **ep,
-               Entry                   **matched
-)
+       Operation               *op,
+       SlapReply               *rs,
+       struct berval           *ndn,
+       Entry                   **ep,
+       Entry                   **matched )
 {
        monitor_info_t *mi = (monitor_info_t *)op->o_bd->be_private;
        int                     rc;
@@ -219,7 +213,9 @@ monitor_cache_dn2entry(
        }
 
        if ( !rc ) {
+               monitor_cache_lock( *ep );
                monitor_cache_release( mi, e_parent );
+
        } else {
                *matched = e_parent;
        }
@@ -234,8 +230,7 @@ monitor_cache_dn2entry(
 int
 monitor_cache_release(
        monitor_info_t  *mi,
-       Entry           *e
-)
+       Entry           *e )
 {
        monitor_entry_t *mp;
 
@@ -254,7 +249,9 @@ monitor_cache_release(
                mc = avl_delete( &mi->mi_cache,
                                ( caddr_t )&tmp_mc, monitor_cache_cmp );
                ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
-               ch_free( mc );
+               if ( mc != NULL ) {
+                       ch_free( mc );
+               }
                
                ldap_pvt_thread_mutex_unlock( &mp->mp_mutex );
                ldap_pvt_thread_mutex_destroy( &mp->mp_mutex );
index d2e7982c004372afa2360d50f303c827f7f9b8f9..db3d6ab5be7a2823bf8bfa1305ed29e40662697c 100644 (file)
@@ -39,14 +39,17 @@ monitor_send_children(
 )
 {
        monitor_info_t  *mi = ( monitor_info_t * )op->o_bd->be_private;
-       Entry                   *e, *e_tmp, *e_ch;
+       Entry                   *e,
+                               *e_tmp,
+                               *e_ch = NULL,
+                               *e_nonvolatile = NULL;
        monitor_entry_t *mp;
-       int                     rc;
+       int                     rc,
+                               nonvolatile = 0;
 
        mp = ( monitor_entry_t * )e_parent->e_private;
-       e = mp->mp_children;
+       e_nonvolatile = e = mp->mp_children;
 
-       e_ch = NULL;
        if ( MONITOR_HAS_VOLATILE_CH( mp ) ) {
                monitor_entry_create( op, rs, NULL, e_parent, &e_ch );
        }
@@ -64,7 +67,6 @@ monitor_send_children(
                /* if no persistent, return only volatile */
                if ( e == NULL ) {
                        e = e_ch;
-                       monitor_cache_lock( e_ch );
 
                /* else append persistent to volatile */
                } else {
@@ -83,13 +85,27 @@ monitor_send_children(
        }
 
        /* return entries */
-       for ( ; e != NULL; ) {
-               mp = ( monitor_entry_t * )e->e_private;
-
+       for ( monitor_cache_lock( e ); e != NULL; ) {
                monitor_entry_update( op, rs, e );
 
                if ( op->o_abandon ) {
-                       monitor_cache_release( mi, e );
+                       /* FIXME: may leak generated children */
+                       if ( nonvolatile == 0 ) {
+                               for ( e_tmp = e; e_tmp != NULL; ) {
+                                       mp = ( monitor_entry_t * )e_tmp->e_private;
+                                       e = e_tmp;
+                                       e_tmp = mp->mp_next;
+                                       monitor_cache_release( mi, e );
+
+                                       if ( e_tmp == e_nonvolatile ) {
+                                               break;
+                                       }
+                               }
+
+                       } else {
+                               monitor_cache_release( mi, e );
+                       }
+
                        return SLAPD_ABANDON;
                }
                
@@ -101,22 +117,46 @@ monitor_send_children(
                        rs->sr_entry = NULL;
                }
 
-               if ( ( mp->mp_children || MONITOR_HAS_VOLATILE_CH( mp ) )
-                               && sub )
-               {
+               mp = ( monitor_entry_t * )e->e_private;
+               e_tmp = mp->mp_next;
+
+               if ( sub ) {
                        rc = monitor_send_children( op, rs, e, sub );
                        if ( rc ) {
-                               monitor_cache_release( mi, e );
+                               /* FIXME: may leak generated children */
+                               if ( nonvolatile == 0 ) {
+                                       for ( e_tmp = e; e_tmp != NULL; ) {
+                                               mp = ( monitor_entry_t * )e_tmp->e_private;
+                                               e = e_tmp;
+                                               e_tmp = mp->mp_next;
+                                               monitor_cache_release( mi, e );
+       
+                                               if ( e_tmp == e_nonvolatile ) {
+                                                       break;
+                                               }
+                                       }
+
+                               } else {
+                                       monitor_cache_release( mi, e );
+                               }
+
                                return( rc );
                        }
                }
 
-               e_tmp = mp->mp_next;
                if ( e_tmp != NULL ) {
                        monitor_cache_lock( e_tmp );
                }
-               monitor_cache_release( mi, e );
+
+               if ( !sub ) {
+                       /* otherwise the recursive call already released */
+                       monitor_cache_release( mi, e );
+               }
+
                e = e_tmp;
+               if ( e == e_nonvolatile ) {
+                       nonvolatile = 1;
+               }
        }
        
        return LDAP_SUCCESS;