MINOR: chunks: implement a simple dynamic allocator for trash buffers
The trash buffers are becoming increasingly complex to deal with due to the code's modularity allowing some functions to be chained and causing the same chunk buffers to be used multiple times along the chain, possibly corrupting each other. In fact the trash were designed from scratch for explicitly not surviving a function call but string manipulation makes this impossible most of the time while not fullfilling the need for reliable temporary chunks. Here we introduce the ability to allocate a temporary trash chunk which is reserved, so that it will not conflict with the trash chunks other functions use, and will even support reentrant calls (eg: build_logline). For this, we create a new pool which is exactly the size of a usual chunk buffer plus the size of the chunk struct so that these chunks when allocated are exactly the same size as the ones returned by get_trash_buffer(). These chunks may fail so the caller must check them, and the caller is also responsible for freeing them. The code focuses on minimal changes and ease of reliable backporting because it will be needed in stable versions in order to support next patch.
This commit is contained in:
parent
26c6eb8383
commit
b686afd568
@ -26,6 +26,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <common/config.h>
|
||||
#include <common/memory.h>
|
||||
|
||||
|
||||
/* describes a chunk of string */
|
||||
@ -35,6 +36,8 @@ struct chunk {
|
||||
int len; /* current size of the string from first to last char. <0 = uninit. */
|
||||
};
|
||||
|
||||
struct pool_head *pool2_trash;
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
int chunk_printf(struct chunk *chk, const char *fmt, ...)
|
||||
@ -50,6 +53,16 @@ int chunk_strcasecmp(const struct chunk *chk, const char *str);
|
||||
int alloc_trash_buffers(int bufsize);
|
||||
void free_trash_buffers(void);
|
||||
struct chunk *get_trash_chunk(void);
|
||||
struct chunk *alloc_trash_chunk(void);
|
||||
|
||||
/*
|
||||
* free a trash chunk allocated by alloc_trash_chunk(). NOP on NULL.
|
||||
*/
|
||||
static inline void free_trash_chunk(struct chunk *chunk)
|
||||
{
|
||||
pool_free2(pool2_trash, chunk);
|
||||
}
|
||||
|
||||
|
||||
static inline void chunk_reset(struct chunk *chk)
|
||||
{
|
||||
|
25
src/chunk.c
25
src/chunk.c
@ -29,6 +29,9 @@ static int trash_size;
|
||||
static char *trash_buf1;
|
||||
static char *trash_buf2;
|
||||
|
||||
/* the trash pool for reentrant allocations */
|
||||
struct pool_head *pool2_trash = NULL;
|
||||
|
||||
/*
|
||||
* Returns a pre-allocated and initialized trash chunk that can be used for any
|
||||
* type of conversion. Two chunks and their respective buffers are alternatively
|
||||
@ -63,7 +66,8 @@ int alloc_trash_buffers(int bufsize)
|
||||
trash_size = bufsize;
|
||||
trash_buf1 = (char *)my_realloc2(trash_buf1, bufsize);
|
||||
trash_buf2 = (char *)my_realloc2(trash_buf2, bufsize);
|
||||
return trash_buf1 && trash_buf2;
|
||||
pool2_trash = create_pool("trash", sizeof(struct chunk) + bufsize, MEM_F_EXACT);
|
||||
return trash_buf1 && trash_buf2 && pool2_trash;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -77,6 +81,25 @@ void free_trash_buffers(void)
|
||||
trash_buf1 = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a trash chunk from the reentrant pool. The buffer starts at the
|
||||
* end of the chunk. This chunk must be freed using free_trash_chunk(). This
|
||||
* call may fail and the caller is responsible for checking that the returned
|
||||
* pointer is not NULL.
|
||||
*/
|
||||
struct chunk *alloc_trash_chunk(void)
|
||||
{
|
||||
struct chunk *chunk;
|
||||
|
||||
chunk = pool_alloc2(pool2_trash);
|
||||
if (chunk) {
|
||||
char *buf = (char *)chunk + sizeof(struct chunk);
|
||||
*buf = 0;
|
||||
chunk_init(chunk, buf, pool2_trash->size - sizeof(struct chunk));
|
||||
}
|
||||
return chunk;
|
||||
}
|
||||
|
||||
/*
|
||||
* Does an snprintf() at the beginning of chunk <chk>, respecting the limit of
|
||||
* at most chk->size chars. If the chk->len is over, nothing is added. Returns
|
||||
|
@ -1545,6 +1545,7 @@ static void deinit(void)
|
||||
pool_destroy2(pool2_stream);
|
||||
pool_destroy2(pool2_session);
|
||||
pool_destroy2(pool2_connection);
|
||||
pool_destroy2(pool2_trash);
|
||||
pool_destroy2(pool2_buffer);
|
||||
pool_destroy2(pool2_requri);
|
||||
pool_destroy2(pool2_task);
|
||||
|
Loading…
Reference in New Issue
Block a user