Enhance buffer handling by changing gwbuf_free to free the whole list of buffers (although it could contain only one buffer). Add gwbuf_count to give number of buffers in a buffer list (for convenience in debugging). Add gwbuf_alloc_and_load to simplify putting data into a new buffer.
This commit is contained in:
@ -20,7 +20,7 @@
|
|||||||
* @file buffer.h - The MaxScale buffer management functions
|
* @file buffer.h - The MaxScale buffer management functions
|
||||||
*
|
*
|
||||||
* The buffer management is based on the principle of a linked list
|
* The buffer management is based on the principle of a linked list
|
||||||
* of variable size buffer, the intention beign to allow longer
|
* of variable size buffer, the intention being to allow longer
|
||||||
* content to be buffered in a list and minimise any need to copy
|
* content to be buffered in a list and minimise any need to copy
|
||||||
* data between buffers.
|
* data between buffers.
|
||||||
*
|
*
|
||||||
@ -37,6 +37,8 @@
|
|||||||
* the gwbuf_append process
|
* the gwbuf_append process
|
||||||
* 09/11/2015 Martin Brampton Add buffer tracing (conditional compilation),
|
* 09/11/2015 Martin Brampton Add buffer tracing (conditional compilation),
|
||||||
* accessed by "show buffers" maxadmin command
|
* accessed by "show buffers" maxadmin command
|
||||||
|
* 20/12/2015 Martin Brampton Change gwbuf_free to free the whole list; add the
|
||||||
|
* gwbuf_count and gwbuf_alloc_and_load functions.
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
@ -56,6 +58,7 @@
|
|||||||
static HASHTABLE *buffer_hashtable = NULL;
|
static HASHTABLE *buffer_hashtable = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void gwbuf_free_one(GWBUF *buf);
|
||||||
static buffer_object_t* gwbuf_remove_buffer_object(GWBUF* buf,
|
static buffer_object_t* gwbuf_remove_buffer_object(GWBUF* buf,
|
||||||
buffer_object_t* bufobj);
|
buffer_object_t* bufobj);
|
||||||
|
|
||||||
@ -71,7 +74,7 @@ static void gwbuf_remove_from_hashtable(GWBUF *buf);
|
|||||||
*
|
*
|
||||||
* For now we allocate memory directly from malloc for buffer the management
|
* For now we allocate memory directly from malloc for buffer the management
|
||||||
* structure and the actual data buffer itself. We may swap at a future date
|
* structure and the actual data buffer itself. We may swap at a future date
|
||||||
* to a more effecient mechanism.
|
* to a more efficient mechanism.
|
||||||
*
|
*
|
||||||
* @param size The size in bytes of the data area required
|
* @param size The size in bytes of the data area required
|
||||||
* @return Pointer to the buffer structure or NULL if memory could not
|
* @return Pointer to the buffer structure or NULL if memory could not
|
||||||
@ -135,6 +138,25 @@ retblock:
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate a new gateway buffer structure of size bytes and load with data.
|
||||||
|
*
|
||||||
|
* @param size The size in bytes of the data area required
|
||||||
|
* @param data Pointer to the data (size bytes) to be loaded
|
||||||
|
* @return Pointer to the buffer structure or NULL if memory could not
|
||||||
|
* be allocated.
|
||||||
|
*/
|
||||||
|
GWBUF *
|
||||||
|
gwbuf_alloc_and_load(unsigned int size, void *data)
|
||||||
|
{
|
||||||
|
GWBUF *rval;
|
||||||
|
if ((rval = gwbuf_alloc(size)) != NULL)
|
||||||
|
{
|
||||||
|
memcpy(GWBUF_DATA(rval), data, size);
|
||||||
|
}
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(BUFFER_TRACE)
|
#if defined(BUFFER_TRACE)
|
||||||
/**
|
/**
|
||||||
* Store a trace of buffer creation
|
* Store a trace of buffer creation
|
||||||
@ -232,17 +254,37 @@ dprintAllBuffers(void *pdcb)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free a gateway buffer
|
* Free a list of gateway buffers
|
||||||
*
|
*
|
||||||
* @param buf The buffer to free
|
* @param buf The head of the list of buffers to free
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gwbuf_free(GWBUF *buf)
|
gwbuf_free(GWBUF *buf)
|
||||||
|
{
|
||||||
|
GWBUF *nextbuf;
|
||||||
|
BUF_PROPERTY *prop;
|
||||||
|
buffer_object_t *bo;
|
||||||
|
|
||||||
|
while (buf)
|
||||||
|
{
|
||||||
|
CHK_GWBUF(buf);
|
||||||
|
nextbuf = buf->next;
|
||||||
|
gwbuf_free_one(buf);
|
||||||
|
buf = nextbuf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free a single gateway buffer
|
||||||
|
*
|
||||||
|
* @param buf The buffer to free
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
gwbuf_free_one(GWBUF *buf)
|
||||||
{
|
{
|
||||||
BUF_PROPERTY *prop;
|
BUF_PROPERTY *prop;
|
||||||
buffer_object_t *bo;
|
buffer_object_t *bo;
|
||||||
|
|
||||||
CHK_GWBUF(buf);
|
|
||||||
if (atomic_add(&buf->sbuf->refcount, -1) == 1)
|
if (atomic_add(&buf->sbuf->refcount, -1) == 1)
|
||||||
{
|
{
|
||||||
free(buf->sbuf->data);
|
free(buf->sbuf->data);
|
||||||
@ -493,7 +535,7 @@ gwbuf_consume(GWBUF *head, unsigned int length)
|
|||||||
head->next->tail = head->tail;
|
head->next->tail = head->tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
gwbuf_free(head);
|
gwbuf_free_one(head);
|
||||||
}
|
}
|
||||||
|
|
||||||
ss_dassert(rval == NULL || (rval->end > rval->start));
|
ss_dassert(rval == NULL || (rval->end > rval->start));
|
||||||
@ -523,6 +565,26 @@ gwbuf_length(GWBUF *head)
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the number of individual buffers in the linked list.
|
||||||
|
*
|
||||||
|
* Currently not used, provided mainly for use during debugging sessions.
|
||||||
|
*
|
||||||
|
* @param head The current head of the linked list
|
||||||
|
* @return The number of bytes of data in the linked list
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
gwbuf_count(GWBUF *head)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
while (head)
|
||||||
|
{
|
||||||
|
result++;
|
||||||
|
head = head->next;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trim bytes form the end of a GWBUF structure. If the
|
* Trim bytes form the end of a GWBUF structure. If the
|
||||||
* buffer has n_bytes or less then it will be freed and
|
* buffer has n_bytes or less then it will be freed and
|
||||||
@ -599,7 +661,7 @@ void gwbuf_set_type(
|
|||||||
* @param buf GWBUF where object is added
|
* @param buf GWBUF where object is added
|
||||||
* @param id Type identifier for object
|
* @param id Type identifier for object
|
||||||
* @param data Object data
|
* @param data Object data
|
||||||
* @param donefun_dp Clean-up function to be executed before buffer is freed.
|
* @param donefun_fp Clean-up function to be executed before buffer is freed.
|
||||||
*/
|
*/
|
||||||
void gwbuf_add_buffer_object(GWBUF* buf,
|
void gwbuf_add_buffer_object(GWBUF* buf,
|
||||||
bufobj_id_t id,
|
bufobj_id_t id,
|
||||||
|
@ -188,6 +188,7 @@ typedef struct gwbuf
|
|||||||
* Function prototypes for the API to maniplate the buffers
|
* Function prototypes for the API to maniplate the buffers
|
||||||
*/
|
*/
|
||||||
extern GWBUF *gwbuf_alloc(unsigned int size);
|
extern GWBUF *gwbuf_alloc(unsigned int size);
|
||||||
|
extern GWBUF *gwbuf_alloc_and_load(unsigned int size, void *data);
|
||||||
extern void gwbuf_free(GWBUF *buf);
|
extern void gwbuf_free(GWBUF *buf);
|
||||||
extern GWBUF *gwbuf_clone(GWBUF *buf);
|
extern GWBUF *gwbuf_clone(GWBUF *buf);
|
||||||
extern GWBUF *gwbuf_append(GWBUF *head, GWBUF *tail);
|
extern GWBUF *gwbuf_append(GWBUF *head, GWBUF *tail);
|
||||||
@ -195,6 +196,7 @@ extern GWBUF *gwbuf_consume(GWBUF *head, unsigned int length);
|
|||||||
extern GWBUF *gwbuf_trim(GWBUF *head, unsigned int length);
|
extern GWBUF *gwbuf_trim(GWBUF *head, unsigned int length);
|
||||||
extern GWBUF *gwbuf_rtrim(GWBUF *head, unsigned int length);
|
extern GWBUF *gwbuf_rtrim(GWBUF *head, unsigned int length);
|
||||||
extern unsigned int gwbuf_length(GWBUF *head);
|
extern unsigned int gwbuf_length(GWBUF *head);
|
||||||
|
extern int gwbuf_count(GWBUF *head);
|
||||||
extern GWBUF *gwbuf_clone_portion(GWBUF *head, size_t offset, size_t len);
|
extern GWBUF *gwbuf_clone_portion(GWBUF *head, size_t offset, size_t len);
|
||||||
extern GWBUF *gwbuf_clone_transform(GWBUF *head, gwbuf_type_t type);
|
extern GWBUF *gwbuf_clone_transform(GWBUF *head, gwbuf_type_t type);
|
||||||
extern GWBUF *gwbuf_clone_all(GWBUF* head);
|
extern GWBUF *gwbuf_clone_all(GWBUF* head);
|
||||||
|
Reference in New Issue
Block a user