]> git.sur5r.net Git - openldap/commitdiff
More memory context tweaks
authorHoward Chu <hyc@openldap.org>
Thu, 10 Apr 2003 06:21:53 +0000 (06:21 +0000)
committerHoward Chu <hyc@openldap.org>
Thu, 10 Apr 2003 06:21:53 +0000 (06:21 +0000)
servers/slapd/connection.c
servers/slapd/entry.c
servers/slapd/filter.c
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/sl_malloc.c

index d81299aad4612c3f819b6cd9374af4f2fa9c3183..09410a3f2737fb9f21f361735c7ba5a425ef0082 100644 (file)
@@ -889,6 +889,7 @@ connection_operation( void *ctx, void *arg_v )
 #endif /* SLAPD_MONITOR */
        Connection *conn = op->o_conn;
        void *memctx;
+       ber_len_t memsiz;
 
        ldap_pvt_thread_mutex_lock( &num_ops_mutex );
        num_ops_initiated++;
@@ -915,8 +916,11 @@ connection_operation( void *ctx, void *arg_v )
         * storage for most mallocs.
         */
 #define        SLAB_SIZE       1048576
+       memsiz = ber_len( op->o_ber ) * 32;
+       if ( SLAB_SIZE > memsiz ) memsiz = SLAB_SIZE;
+
        if ( tag == LDAP_REQ_SEARCH ) {
-               memctx = sl_mem_create( SLAB_SIZE, ctx );
+               memctx = sl_mem_create( memsiz, ctx );
                ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, memctx );
                op->o_tmpmemctx = memctx;
                op->o_tmpmfuncs = &sl_mfuncs;
@@ -1072,6 +1076,7 @@ operations_error:
 
 co_op_free:
 
+       ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, NULL );
        slap_op_free( op );
 
 no_co_op_free:
index a494a04424360f2b0b85932c792c9fd08647091e..d01e5259280640c97d63b5634203fab0af9f22be 100644 (file)
@@ -442,8 +442,6 @@ entry_id_cmp( const void *v_e1, const void *v_e2 )
        return( e1->e_id < e2->e_id ? -1 : (e1->e_id > e2->e_id ? 1 : 0) );
 }
 
-#ifdef SLAPD_BDB
-
 /* This is like a ber_len */
 static ber_len_t
 entry_lenlen(ber_len_t len)
@@ -495,33 +493,22 @@ entry_getlen(unsigned char **buf)
        return len;
 }
 
-/* Flatten an Entry into a buffer. The buffer is filled with just the
- * strings/bervals of all the entry components. Each field is preceded
- * by its length, encoded the way ber_put_len works. Every field is NUL
- * terminated.  The entire buffer size is precomputed so that a single
- * malloc can be performed. The entry size is also recorded,
- * to aid in entry_decode.
- */
-int entry_encode(Entry *e, struct berval *bv)
+/* Add up the size of the entry for a flattened buffer */
+void entry_flatsize(Entry *e, ber_len_t *psiz, ber_len_t *plen, int norm)
 {
        ber_len_t siz = sizeof(Entry);
        ber_len_t len, dnlen, ndnlen;
        int i;
        Attribute *a;
-       unsigned char *ptr;
 
-#ifdef NEW_LOGGING
-       LDAP_LOG( OPERATION, DETAIL1, "entry_encode: id: 0x%08lx  \"%s\"\n",
-               (long) e->e_id, e->e_dn, 0 );
-#else
-       Debug( LDAP_DEBUG_TRACE, "=> entry_encode(0x%08lx): %s\n",
-               (long) e->e_id, e->e_dn, 0 );
-#endif
        dnlen = e->e_name.bv_len;
-       ndnlen = e->e_nname.bv_len;
-       len = dnlen + ndnlen + 2;       /* two trailing NUL bytes */
+       len = dnlen + 1;        /* trailing NUL byte */
        len += entry_lenlen(dnlen);
-       len += entry_lenlen(ndnlen);
+       if (norm) {
+               ndnlen = e->e_nname.bv_len;
+               len += ndnlen + 1;
+               len += entry_lenlen(ndnlen);
+       }
        for (a=e->e_attrs; a; a=a->a_next) {
                /* For AttributeDesc, we only store the attr name */
                siz += sizeof(Attribute);
@@ -534,7 +521,7 @@ int entry_encode(Entry *e, struct berval *bv)
                }
                len += entry_lenlen(i);
                siz += sizeof(struct berval);   /* empty berval at end */
-               if (a->a_nvals != a->a_vals) {
+               if (norm && a->a_nvals != a->a_vals) {
                        for (i=0; a->a_nvals[i].bv_val; i++) {
                                siz += sizeof(struct berval);
                                len += a->a_nvals[i].bv_len + 1;
@@ -548,6 +535,37 @@ int entry_encode(Entry *e, struct berval *bv)
        }
        len += 1;       /* NUL byte at end */
        len += entry_lenlen(siz);
+       *psiz = siz;
+       *plen = len;
+}
+
+/* Flatten an Entry into a buffer. The buffer is filled with just the
+ * strings/bervals of all the entry components. Each field is preceded
+ * by its length, encoded the way ber_put_len works. Every field is NUL
+ * terminated.  The entire buffer size is precomputed so that a single
+ * malloc can be performed. The entry size is also recorded,
+ * to aid in entry_decode.
+ */
+int entry_encode(Entry *e, struct berval *bv)
+{
+       ber_len_t siz = sizeof(Entry);
+       ber_len_t len, dnlen, ndnlen;
+       int i;
+       Attribute *a;
+       unsigned char *ptr;
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( OPERATION, DETAIL1, "entry_encode: id: 0x%08lx  \"%s\"\n",
+               (long) e->e_id, e->e_dn, 0 );
+#else
+       Debug( LDAP_DEBUG_TRACE, "=> entry_encode(0x%08lx): %s\n",
+               (long) e->e_id, e->e_dn, 0 );
+#endif
+       dnlen = e->e_name.bv_len;
+       ndnlen = e->e_nname.bv_len;
+
+       entry_flatsize( e, &siz, &len, 1 );
+
        bv->bv_len = len;
        bv->bv_val = ch_malloc(len);
        ptr = (unsigned char *)bv->bv_val;
@@ -724,4 +742,3 @@ int entry_decode(struct berval *bv, Entry **e)
        *e = x;
        return 0;
 }
-#endif
index 87c10418eb0169060d05baa5c2981b637ad6f11c..9312bb97e87e1d15281c62079d9f221dbd7e3230 100644 (file)
@@ -1195,8 +1195,6 @@ vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr )
        ValuesReturnFilter      *p;
        struct berval tmp;
        ber_len_t len;
-       BER_MEMREALLOC_FN *reallo = op->o_tmpmemctx ? sl_realloc :
-               (BER_MEMREALLOC_FN *)ch_realloc;
 
        if ( vrf == NULL ) {
                ber_str2bv_x( "No filter!", sizeof("No filter!")-1, 1, fstr, op->o_tmpmemctx );
@@ -1214,7 +1212,7 @@ vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr )
                simple_vrFilter2bv( op, p, &tmp );
                        
                fstr->bv_len += tmp.bv_len;
-               fstr->bv_val = reallo( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
+               fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
 
                snprintf( &fstr->bv_val[len-1], tmp.bv_len + 2, 
                        /*"("*/ "%s)", tmp.bv_val );
@@ -1228,8 +1226,6 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr
 {
        struct berval tmp;
        ber_len_t len;
-       BER_MEMREALLOC_FN *reallo = op->o_tmpmemctx ? sl_realloc :
-               (BER_MEMREALLOC_FN *) ch_realloc;
 
        if ( vrf == NULL ) {
                ber_str2bv_x( "No filter!", sizeof("No filter!")-1, 1, fstr, op->o_tmpmemctx );
@@ -1306,7 +1302,7 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr
                        filter_escape_value_x( &vrf->vrf_sub_initial, &tmp, op->o_tmpmemctx );
 
                        fstr->bv_len += tmp.bv_len;
-                       fstr->bv_val = reallo( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
+                       fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
 
                        snprintf( &fstr->bv_val[len-2], tmp.bv_len+3,
                                /* "(attr=" */ "%s*)",
@@ -1322,7 +1318,7 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr
                                filter_escape_value_x( &vrf->vrf_sub_any[i], &tmp, op->o_tmpmemctx );
 
                                fstr->bv_len += tmp.bv_len + 1;
-                               fstr->bv_val = reallo( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
+                               fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
 
                                snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
                                        /* "(attr=[init]*[any*]" */ "%s*)",
@@ -1337,7 +1333,7 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr
                        filter_escape_value_x( &vrf->vrf_sub_final, &tmp, op->o_tmpmemctx );
 
                        fstr->bv_len += tmp.bv_len;
-                       fstr->bv_val = reallo( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
+                       fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
 
                        snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
                                /* "(attr=[init*][any*]" */ "%s)",
index ab25abde09016c2049bbd4c7a22abcc931b98659..235d0a447e13f4375d986ac4ac04a644e042a2da 100644 (file)
@@ -440,6 +440,8 @@ LDAP_SLAPD_F (int) entry_destroy LDAP_P((void));
 LDAP_SLAPD_F (Entry *) str2entry LDAP_P(( char *s ));
 LDAP_SLAPD_F (char *) entry2str LDAP_P(( Entry *e, int *len ));
 
+LDAP_SLAPD_F (void) entry_flatsize LDAP_P((
+       Entry *e, ber_len_t *siz, ber_len_t *len, int norm ));
 LDAP_SLAPD_F (int) entry_decode LDAP_P(( struct berval *bv, Entry **e ));
 LDAP_SLAPD_F (int) entry_encode LDAP_P(( Entry *e, struct berval *bv ));
 
@@ -968,6 +970,8 @@ LDAP_SLAPD_F (void *) sl_realloc LDAP_P(( void *block, ber_len_t size, void *ctx
 LDAP_SLAPD_F (void *) sl_calloc LDAP_P(( ber_len_t nelem, ber_len_t size, void *ctx ));
 LDAP_SLAPD_F (void) sl_free LDAP_P(( void *, void *ctx ));
 LDAP_SLAPD_F (void *) sl_mem_create LDAP_P(( ber_len_t size, void *ctx ));
+LDAP_SLAPD_F (void *) sl_mark LDAP_P(( void *ctx ));
+LDAP_SLAPD_F (void) sl_release LDAP_P(( void *, void *ctx ));
 
 /*
  * starttls.c
index 3eb6080d44cb8aa092f5d4928c56a264d9eb77d7..5e9503ad613e31e4e2071d0bf21ea06c671fde3f 100644 (file)
@@ -587,6 +587,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
        computed_attr_context    ctx;
        AttributeName   *anp;
 #endif
+       void            *mark = NULL;
 
        AttributeDescription *ad_entry = slap_schema.si_ad_entry;
 
@@ -611,6 +612,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                rs->sr_entry->e_name.bv_val, op->ors_attrsonly ? " (attrsOnly)" : "", 0 );
 #endif
 
+       mark = sl_mark( op->o_tmpmemctx );
+
        if ( ! access_allowed( op, rs->sr_entry, ad_entry, NULL, ACL_READ, NULL ) )
        {
 #ifdef NEW_LOGGING
@@ -623,6 +626,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                    0, 0, 0 );
 #endif
 
+               sl_release( mark, op->o_tmpmemctx );
                return( 1 );
        }
 
@@ -633,7 +637,17 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
            ber = op->o_res_ber;
        else
 #endif
-       ber_init_w_nullc( ber, LBER_USE_DER );
+       {
+               ber_len_t       siz, len;
+               struct berval   bv;
+
+               entry_flatsize( rs->sr_entry, &siz, &len, 0 );
+               bv.bv_len = siz + len;
+               bv.bv_val = op->o_tmpalloc(bv.bv_len, op->o_tmpmemctx );
+
+               ber_init2( ber, &bv, LBER_USE_DER );
+               ber_set_option( ber, LBER_OPT_BER_MEMCTX, op->o_tmpmemctx );
+       }
 
 #ifdef LDAP_CONNECTIONLESS
        if (op->o_conn && op->o_conn->c_is_udp && op->o_protocol == LDAP_VERSION2) {
@@ -686,15 +700,15 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                size = i * sizeof(char *) + k;
                if ( size > 0 ) {
                        char    *a_flags;
-                       e_flags = SLAP_CALLOC ( 1, i * sizeof(char *) + k );
+                       e_flags = sl_calloc ( 1, i * sizeof(char *) + k, op->o_tmpmemctx );
                        if( e_flags == NULL ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( OPERATION, ERR, 
-                                       "send_search_entry: conn %lu SLAP_CALLOC failed\n",
+                                       "send_search_entry: conn %lu sl_calloc failed\n",
                                        op->o_connid : 0, 0, 0 );
 #else
                        Debug( LDAP_DEBUG_ANY, 
-                                       "send_search_entry: SLAP_CALLOC failed\n", 0, 0, 0 );
+                                       "send_search_entry: sl_calloc failed\n", 0, 0, 0 );
 #endif
                                ber_free( ber, 1 );
        
@@ -866,7 +880,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                         * Reuse previous memory - we likely need less space
                         * for operational attributes
                         */
-                       tmp = SLAP_REALLOC ( e_flags, i * sizeof(char *) + k );
+                       tmp = sl_realloc( e_flags, i * sizeof(char *) + k, op->o_tmpmemctx );
                        if ( tmp == NULL ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( OPERATION, ERR, 
@@ -1082,7 +1096,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 
        /* free e_flags */
        if ( e_flags ) {
-               free( e_flags );
+               sl_free( e_flags, op->o_tmpmemctx );
                e_flags = NULL;
        }
 
@@ -1116,6 +1130,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 #endif
                ber_free_buf( ber );
                send_ldap_error( op, rs, LDAP_OTHER, "encode entry end error" );
+               sl_release( mark, op->o_tmpmemctx );
                return( 1 );
        }
 
@@ -1136,6 +1151,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                        0, 0, 0 );
 #endif
 
+               sl_release( mark, op->o_tmpmemctx );
                return -1;
        }
        rs->sr_nentries++;
@@ -1163,7 +1179,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
        rc = 0;
 
 error_return:;
-       if ( e_flags ) free( e_flags );
+       sl_release( mark, op->o_tmpmemctx );
+       if ( e_flags ) sl_free( e_flags, op->o_tmpmemctx );
        return( rc );
 }
 
index d2223a2ab2afb95ccfcc0cdb679735dbdf14932f..6d81abeab871b1e26f63a7a6a2100be628dce1d8 100644 (file)
@@ -91,14 +91,13 @@ sl_malloc(
 
        if (sh->h_last + size >= sh->h_end ) {
 #ifdef NEW_LOGGING
-               LDAP_LOG( OPERATION, ERR
-                          "sl_malloc: allocation of %lu bytes failed\n", (long)size, 0,0 );
+               LDAP_LOG( OPERATION, INFO
+                          "sl_malloc of %lu bytes failed, using ch_malloc\n", (long)size, 0,0 );
 #else
-               Debug( LDAP_DEBUG_ANY, "sl_malloc of %lu bytes failed\n",
-                       (long) size, 0, 0 );
+               Debug( LDAP_DEBUG_TRACE,
+                          "sl_malloc of %lu bytes failed, using ch_malloc\n", (long)size, 0,0 );
 #endif
-               assert( 0 );
-               exit( EXIT_FAILURE );
+               return ch_malloc( size );
        }
        new = sh->h_last;
        *new++ = size - sizeof(ber_len_t);
@@ -129,16 +128,9 @@ sl_realloc( void *ptr, ber_len_t size, void *ctx )
 
        if ( ptr == NULL ) return sl_malloc( size, ctx );
 
+       /* Not our memory? */
        if ( ptr < sh->h_base || ptr >= sh->h_end ) {
-#ifdef NEW_LOGGING
-               LDAP_LOG( OPERATION, ERR, 
-                          "sl_free: not mine: 0x%lx\n", (long)ptr, 0,0 );
-#else
-               Debug( LDAP_DEBUG_ANY,
-                          "sl_free: not mine: 0x%lx\n", (long)ptr, 0,0 );
-#endif
-               assert( 0 );
-               exit( EXIT_FAILURE );
+               return ch_realloc( ptr, size );
        }
 
        if ( size == 0 ) return NULL;
@@ -147,9 +139,8 @@ sl_realloc( void *ptr, ber_len_t size, void *ctx )
        size += pad + sizeof( ber_len_t );
        size &= ~pad;
 
-       /* We always alloc a new block */
+       /* Never shrink blocks, always alloc if growth needed */
        if (size <= p[-1]) {
-               p[-1] = size;
                new = p;
        } else {
                new = sl_malloc( size, ctx );
@@ -164,14 +155,24 @@ sl_free( void *ptr, void *ctx )
        struct slab_heap *sh = ctx;
 
        if ( ptr < sh->h_base || ptr >= sh->h_end ) {
-#ifdef NEW_LOGGING
-               LDAP_LOG( OPERATION, ERR, 
-                          "sl_free: not mine: 0x%lx\n", (long)ptr, 0,0 );
-#else
-               Debug( LDAP_DEBUG_ANY,
-                          "sl_free: not mine: 0x%lx\n", (long)ptr, 0,0 );
-#endif
-               assert( 0 );
-               exit( EXIT_FAILURE );
+               ch_free( ptr );
        }
 }
+
+void
+sl_release( void *ptr, void *ctx )
+{
+       struct slab_heap *sh = ctx;
+
+       if ( ptr >= sh->h_base && ptr <= sh->h_end ) {
+               sh->h_last = ptr;
+       }
+}
+
+void *
+sl_mark( void *ctx )
+{
+       struct slab_heap *sh = ctx;
+
+       return sh->h_last;
+}