mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-04 06:01:23 -05:00
ITS#6437, slap_sl_mem_create():
Bugfix: Switching implementation stack<->pool on an old context could
crash or leak, it ran the wrong implementation's cleanup code.
Cleanup: Factor out identical stack/pool code. Call
slap_sl_mem_destroy(NULL,) instead of copying its pool code.
API change: slap_sl_mem_destroy(key=NULL,) gets a new meaning. Does
not affect current OpenLDAP code, it never passed NULL.
This commit is contained in:
parent
7946c100a4
commit
062021e731
1 changed files with 15 additions and 60 deletions
|
|
@ -26,6 +26,7 @@ static struct slab_object * slap_replenish_sopool(struct slab_heap* sh);
|
|||
static void print_slheap(int level, void *ctx);
|
||||
#endif
|
||||
|
||||
/* Destroy the context, or if key==NULL clean it up for reuse. */
|
||||
void
|
||||
slap_sl_mem_destroy(
|
||||
void *key,
|
||||
|
|
@ -37,10 +38,7 @@ slap_sl_mem_destroy(
|
|||
int order_start = -1, i;
|
||||
struct slab_object *so;
|
||||
|
||||
if (sh->sh_stack) {
|
||||
ber_memfree_x(sh->sh_base, NULL);
|
||||
ber_memfree_x(sh, NULL);
|
||||
} else {
|
||||
if (!sh->sh_stack) {
|
||||
pad_shift = pad - 1;
|
||||
do {
|
||||
order_start++;
|
||||
|
|
@ -72,6 +70,9 @@ slap_sl_mem_destroy(
|
|||
so = LDAP_LIST_NEXT(so, so_link);
|
||||
ch_free(so_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if (key != NULL) {
|
||||
ber_memfree_x(sh->sh_base, NULL);
|
||||
ber_memfree_x(sh, NULL);
|
||||
}
|
||||
|
|
@ -129,8 +130,7 @@ slap_sl_mem_create(
|
|||
size += pad;
|
||||
size &= ~pad;
|
||||
|
||||
if (stack) {
|
||||
if (!sh) {
|
||||
if (!sh) {
|
||||
sh = ch_malloc(sizeof(struct slab_heap));
|
||||
sh->sh_base = ch_malloc(size);
|
||||
#ifdef NO_THREADS
|
||||
|
|
@ -139,22 +139,26 @@ slap_sl_mem_create(
|
|||
ldap_pvt_thread_pool_setkey(ctx, (void *)slap_sl_mem_init,
|
||||
(void *)sh, slap_sl_mem_destroy, NULL, NULL);
|
||||
#endif
|
||||
} else if ( size > (char *)sh->sh_end - (char *)sh->sh_base ) {
|
||||
} else {
|
||||
slap_sl_mem_destroy(NULL, sh);
|
||||
if ( size > (char *)sh->sh_end - (char *)sh->sh_base ) {
|
||||
void *newptr;
|
||||
|
||||
newptr = ch_realloc( sh->sh_base, size );
|
||||
if ( newptr == NULL ) return NULL;
|
||||
sh->sh_base = newptr;
|
||||
}
|
||||
}
|
||||
sh->sh_end = (char *) sh->sh_base + size;
|
||||
|
||||
sh->sh_stack = stack;
|
||||
if (stack) {
|
||||
/* insert dummy len */
|
||||
{
|
||||
ber_len_t *i = sh->sh_base;
|
||||
*i++ = 0;
|
||||
sh->sh_last = i;
|
||||
}
|
||||
sh->sh_end = (char *) sh->sh_base + size;
|
||||
sh->sh_stack = stack;
|
||||
return sh;
|
||||
} else {
|
||||
size_shift = size - 1;
|
||||
do {
|
||||
|
|
@ -165,55 +169,7 @@ slap_sl_mem_create(
|
|||
do {
|
||||
order_start++;
|
||||
} while (pad_shift >>= 1);
|
||||
|
||||
order = order_end - order_start + 1;
|
||||
|
||||
if (!sh) {
|
||||
sh = (struct slab_heap *) ch_malloc(sizeof(struct slab_heap));
|
||||
sh->sh_base = ch_malloc(size);
|
||||
#ifdef NO_THREADS
|
||||
slheap = sh;
|
||||
#else
|
||||
ldap_pvt_thread_pool_setkey(ctx, (void *)slap_sl_mem_init,
|
||||
(void *)sh, slap_sl_mem_destroy, NULL, NULL);
|
||||
#endif
|
||||
} else {
|
||||
for (i = 0; i <= sh->sh_maxorder - order_start; i++) {
|
||||
so = LDAP_LIST_FIRST(&sh->sh_free[i]);
|
||||
while (so) {
|
||||
struct slab_object *so_tmp = so;
|
||||
so = LDAP_LIST_NEXT(so, so_link);
|
||||
LDAP_LIST_INSERT_HEAD(&sh->sh_sopool, so_tmp, so_link);
|
||||
}
|
||||
ch_free(sh->sh_map[i]);
|
||||
}
|
||||
ch_free(sh->sh_free);
|
||||
ch_free(sh->sh_map);
|
||||
|
||||
so = LDAP_LIST_FIRST(&sh->sh_sopool);
|
||||
while (so) {
|
||||
struct slab_object *so_tmp = so;
|
||||
so = LDAP_LIST_NEXT(so, so_link);
|
||||
if (!so_tmp->so_blockhead) {
|
||||
LDAP_LIST_REMOVE(so_tmp, so_link);
|
||||
}
|
||||
}
|
||||
so = LDAP_LIST_FIRST(&sh->sh_sopool);
|
||||
while (so) {
|
||||
struct slab_object *so_tmp = so;
|
||||
so = LDAP_LIST_NEXT(so, so_link);
|
||||
ch_free(so_tmp);
|
||||
}
|
||||
|
||||
if (size > (char *)sh->sh_end - (char *)sh->sh_base) {
|
||||
void *newptr;
|
||||
|
||||
newptr = ch_realloc( sh->sh_base, size );
|
||||
if ( newptr == NULL ) return NULL;
|
||||
sh->sh_base = newptr;
|
||||
}
|
||||
}
|
||||
sh->sh_end = (char *)sh->sh_base + size;
|
||||
sh->sh_maxorder = order_end;
|
||||
|
||||
sh->sh_free = (struct sh_freelist *)
|
||||
|
|
@ -244,9 +200,8 @@ slap_sl_mem_create(
|
|||
sh->sh_map[i] = (unsigned char *) ch_malloc(nummaps);
|
||||
memset(sh->sh_map[i], 0, nummaps);
|
||||
}
|
||||
sh->sh_stack = stack;
|
||||
return sh;
|
||||
}
|
||||
return sh;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
Loading…
Reference in a new issue