From 17760bb3e6655ad263eff6439533b140c6b945a0 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 30 Nov 2015 10:55:21 +0200 Subject: [PATCH] Reindent server/core/buffer.c --- server/core/buffer.c | 861 ++++++++++++++++++++-------------------- server/include/buffer.h | 137 ++++--- 2 files changed, 503 insertions(+), 495 deletions(-) diff --git a/server/core/buffer.c b/server/core/buffer.c index fe50f0303..1c4c811f7 100644 --- a/server/core/buffer.c +++ b/server/core/buffer.c @@ -27,17 +27,17 @@ * @verbatim * Revision History * - * Date Who Description - * 10/06/13 Mark Riddoch Initial implementation - * 11/07/13 Mark Riddoch Add reference count mechanism - * 16/07/2013 Massimiliano Pinto Added command type to gwbuf struct - * 24/06/2014 Mark Riddoch Addition of gwbuf_trim - * 15/07/2014 Mark Riddoch Addition of properties - * 28/08/2014 Mark Riddoch Adition of tail pointer to speed - * the gwbuf_append process + * Date Who Description + * 10/06/13 Mark Riddoch Initial implementation + * 11/07/13 Mark Riddoch Add reference count mechanism + * 16/07/2013 Massimiliano Pinto Added command type to gwbuf struct + * 24/06/2014 Mark Riddoch Addition of gwbuf_trim + * 15/07/2014 Mark Riddoch Addition of properties + * 28/08/2014 Mark Riddoch Adition of tail pointer to speed + * the gwbuf_append process * 09/11/2015 Martin Brampton Add buffer tracing (conditional compilation), * accessed by "show buffers" maxadmin command - * + * * @endverbatim */ #include @@ -56,9 +56,8 @@ static HASHTABLE *buffer_hashtable = NULL; #endif -static buffer_object_t* gwbuf_remove_buffer_object( - GWBUF* buf, - buffer_object_t* bufobj); +static buffer_object_t* gwbuf_remove_buffer_object(GWBUF* buf, + buffer_object_t* bufobj); #if defined(BUFFER_TRACE) static void gwbuf_add_to_hashtable(GWBUF *buf); @@ -74,66 +73,66 @@ static void gwbuf_remove_from_hashtable(GWBUF *buf); * structure and the actual data buffer itself. We may swap at a future date * to a more effecient mechanism. * - * @param size The size in bytes of the data area required - * @return Pointer to the buffer structure or NULL if memory could not - * be allocated. + * @param size The size in bytes of the data area required + * @return Pointer to the buffer structure or NULL if memory could not + * be allocated. */ -GWBUF * +GWBUF * gwbuf_alloc(unsigned int size) { -GWBUF *rval; -SHARED_BUF *sbuf; + GWBUF *rval; + SHARED_BUF *sbuf; - /* Allocate the buffer header */ - if ((rval = (GWBUF *)malloc(sizeof(GWBUF))) == NULL) - { - goto retblock;; - } + /* Allocate the buffer header */ + if ((rval = (GWBUF *)malloc(sizeof(GWBUF))) == NULL) + { + goto retblock; + } - /* Allocate the shared data buffer */ - if ((sbuf = (SHARED_BUF *)malloc(sizeof(SHARED_BUF))) == NULL) - { - free(rval); - rval = NULL; - goto retblock; - } + /* Allocate the shared data buffer */ + if ((sbuf = (SHARED_BUF *)malloc(sizeof(SHARED_BUF))) == NULL) + { + free(rval); + rval = NULL; + goto retblock; + } - /* Allocate the space for the actual data */ - if ((sbuf->data = (unsigned char *)malloc(size)) == NULL) - { - ss_dassert(sbuf->data != NULL); - free(rval); - free(sbuf); - rval = NULL; - goto retblock; - } - spinlock_init(&rval->gwbuf_lock); - rval->start = sbuf->data; - rval->end = (void *)((char *)rval->start+size); - sbuf->refcount = 1; - rval->sbuf = sbuf; - rval->next = NULL; - rval->tail = rval; - rval->hint = NULL; - rval->properties = NULL; - rval->gwbuf_type = GWBUF_TYPE_UNDEFINED; - rval->gwbuf_info = GWBUF_INFO_NONE; - rval->gwbuf_bufobj = NULL; - CHK_GWBUF(rval); + /* Allocate the space for the actual data */ + if ((sbuf->data = (unsigned char *)malloc(size)) == NULL) + { + ss_dassert(sbuf->data != NULL); + free(rval); + free(sbuf); + rval = NULL; + goto retblock; + } + spinlock_init(&rval->gwbuf_lock); + rval->start = sbuf->data; + rval->end = (void *)((char *)rval->start+size); + sbuf->refcount = 1; + rval->sbuf = sbuf; + rval->next = NULL; + rval->tail = rval; + rval->hint = NULL; + rval->properties = NULL; + rval->gwbuf_type = GWBUF_TYPE_UNDEFINED; + rval->gwbuf_info = GWBUF_INFO_NONE; + rval->gwbuf_bufobj = NULL; + CHK_GWBUF(rval); retblock: - if (rval == NULL) - { - char errbuf[STRERROR_BUFLEN]; - MXS_ERROR("Memory allocation failed due to %s.", - strerror_r(errno, errbuf, sizeof(errbuf))); - } + if (rval == NULL) + { + char errbuf[STRERROR_BUFLEN]; + MXS_ERROR("Memory allocation failed due to %s.", + strerror_r(errno, errbuf, sizeof(errbuf))); + } #if defined(BUFFER_TRACE) - else - { - gwbuf_add_to_hashtable(rval); - } + else + { + gwbuf_add_to_hashtable(rval); + } #endif - return rval; + return rval; } #if defined(BUFFER_TRACE) @@ -150,8 +149,8 @@ gwbuf_add_to_hashtable(GWBUF *buf) char **strings; char *tracetext; - size = backtrace (array, 16); - strings = backtrace_symbols (array, size); + size = backtrace(array, 16); + strings = backtrace_symbols(array, size); total = (2 * size) + 1; for (i = 0; i < size; i++) { @@ -171,7 +170,7 @@ gwbuf_add_to_hashtable(GWBUF *buf) if (NULL == buffer_hashtable) { buffer_hashtable = hashtable_alloc(10000, bhashfn, bcmpfn); - hashtable_memory_fns(buffer_hashtable,NULL,NULL,NULL,(HASHMEMORYFN)free); + hashtable_memory_fns(buffer_hashtable, NULL, NULL, NULL, (HASHMEMORYFN)free); } hashtable_add(buffer_hashtable, buf, (void *)tracetext); } @@ -240,42 +239,41 @@ dprintAllBuffers(void *pdcb) void gwbuf_free(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) - { - free(buf->sbuf->data); - free(buf->sbuf); - bo = buf->gwbuf_bufobj; + CHK_GWBUF(buf); + if (atomic_add(&buf->sbuf->refcount, -1) == 1) + { + free(buf->sbuf->data); + free(buf->sbuf); + bo = buf->gwbuf_bufobj; - while (bo != NULL) - { - bo = gwbuf_remove_buffer_object(buf, bo); - } - - } - while (buf->properties) - { - prop = buf->properties; - buf->properties = prop->next; - free(prop->name); - free(prop->value); - free(prop); - } - /** Release the hint */ - while (buf->hint) + while (bo != NULL) { - HINT* h = buf->hint; - buf->hint = buf->hint->next; - hint_free(h); + bo = gwbuf_remove_buffer_object(buf, bo); } + + } + while (buf->properties) + { + prop = buf->properties; + buf->properties = prop->next; + free(prop->name); + free(prop->value); + free(prop); + } + /** Release the hint */ + while (buf->hint) + { + HINT* h = buf->hint; + buf->hint = buf->hint->next; + hint_free(h); + } #if defined(BUFFER_TRACE) - gwbuf_remove_from_hashtable(buf); + gwbuf_remove_from_hashtable(buf); #endif - free(buf); + free(buf); } /** @@ -291,100 +289,97 @@ BUF_PROPERTY *prop; GWBUF * gwbuf_clone(GWBUF *buf) { -GWBUF *rval; + GWBUF *rval; - if ((rval = (GWBUF *)calloc(1,sizeof(GWBUF))) == NULL) - { - ss_dassert(rval != NULL); - char errbuf[STRERROR_BUFLEN]; - MXS_ERROR("Memory allocation failed due to %s.", - strerror_r(errno, errbuf, sizeof(errbuf))); - return NULL; - } + if ((rval = (GWBUF *)calloc(1,sizeof(GWBUF))) == NULL) + { + ss_dassert(rval != NULL); + char errbuf[STRERROR_BUFLEN]; + MXS_ERROR("Memory allocation failed due to %s.", + strerror_r(errno, errbuf, sizeof(errbuf))); + return NULL; + } - atomic_add(&buf->sbuf->refcount, 1); - rval->sbuf = buf->sbuf; - rval->start = buf->start; - rval->end = buf->end; - rval->gwbuf_type = buf->gwbuf_type; - rval->gwbuf_info = buf->gwbuf_info; - rval->gwbuf_bufobj = buf->gwbuf_bufobj; - rval->tail = rval; - rval->next = NULL; - CHK_GWBUF(rval); + atomic_add(&buf->sbuf->refcount, 1); + rval->sbuf = buf->sbuf; + rval->start = buf->start; + rval->end = buf->end; + rval->gwbuf_type = buf->gwbuf_type; + rval->gwbuf_info = buf->gwbuf_info; + rval->gwbuf_bufobj = buf->gwbuf_bufobj; + rval->tail = rval; + rval->next = NULL; + CHK_GWBUF(rval); #if defined(BUFFER_TRACE) - gwbuf_add_to_hashtable(rval); + gwbuf_add_to_hashtable(rval); #endif - return rval; + return rval; } /** * Clone whole GWBUF list instead of single buffer. - * - * @param buf head of the list to be cloned till the tail of it - * + * + * @param buf head of the list to be cloned till the tail of it + * * @return head of the cloned list or NULL if the list was empty. */ -GWBUF* gwbuf_clone_all( - GWBUF* buf) +GWBUF* gwbuf_clone_all(GWBUF* buf) { - GWBUF* rval; - GWBUF* clonebuf; - - if (buf == NULL) - { - return NULL; - } - /** Store the head of the list to rval. */ - clonebuf = gwbuf_clone(buf); - rval = clonebuf; - - while (buf->next) - { - buf = buf->next; - clonebuf->next = gwbuf_clone(buf); - clonebuf = clonebuf->next; - } - return rval; + GWBUF* rval; + GWBUF* clonebuf; + + if (buf == NULL) + { + return NULL; + } + /** Store the head of the list to rval. */ + clonebuf = gwbuf_clone(buf); + rval = clonebuf; + + while (buf->next) + { + buf = buf->next; + clonebuf->next = gwbuf_clone(buf); + clonebuf = clonebuf->next; + } + return rval; } -GWBUF *gwbuf_clone_portion( - GWBUF *buf, - size_t start_offset, - size_t length) +GWBUF *gwbuf_clone_portion(GWBUF *buf, + size_t start_offset, + size_t length) { - GWBUF* clonebuf; - - CHK_GWBUF(buf); - ss_dassert(start_offset+length <= GWBUF_LENGTH(buf)); - - if ((clonebuf = (GWBUF *)malloc(sizeof(GWBUF))) == NULL) - { - ss_dassert(clonebuf != NULL); - char errbuf[STRERROR_BUFLEN]; - MXS_ERROR("Memory allocation failed due to %s.", - strerror_r(errno, errbuf, sizeof(errbuf))); - return NULL; - } - atomic_add(&buf->sbuf->refcount, 1); - clonebuf->sbuf = buf->sbuf; - clonebuf->gwbuf_type = buf->gwbuf_type; /*< clone info bits too */ - clonebuf->start = (void *)((char*)buf->start+start_offset); - clonebuf->end = (void *)((char *)clonebuf->start+length); - clonebuf->gwbuf_type = buf->gwbuf_type; /*< clone the type for now */ - clonebuf->properties = NULL; - clonebuf->hint = NULL; - clonebuf->gwbuf_info = buf->gwbuf_info; - clonebuf->gwbuf_bufobj = buf->gwbuf_bufobj; - clonebuf->next = NULL; - clonebuf->tail = clonebuf; - CHK_GWBUF(clonebuf); + GWBUF* clonebuf; + + CHK_GWBUF(buf); + ss_dassert(start_offset+length <= GWBUF_LENGTH(buf)); + + if ((clonebuf = (GWBUF *)malloc(sizeof(GWBUF))) == NULL) + { + ss_dassert(clonebuf != NULL); + char errbuf[STRERROR_BUFLEN]; + MXS_ERROR("Memory allocation failed due to %s.", + strerror_r(errno, errbuf, sizeof(errbuf))); + return NULL; + } + atomic_add(&buf->sbuf->refcount, 1); + clonebuf->sbuf = buf->sbuf; + clonebuf->gwbuf_type = buf->gwbuf_type; /*< clone info bits too */ + clonebuf->start = (void *)((char*)buf->start+start_offset); + clonebuf->end = (void *)((char *)clonebuf->start+length); + clonebuf->gwbuf_type = buf->gwbuf_type; /*< clone the type for now */ + clonebuf->properties = NULL; + clonebuf->hint = NULL; + clonebuf->gwbuf_info = buf->gwbuf_info; + clonebuf->gwbuf_bufobj = buf->gwbuf_bufobj; + clonebuf->next = NULL; + clonebuf->tail = clonebuf; + CHK_GWBUF(clonebuf); #if defined(BUFFER_TRACE) - gwbuf_add_to_hashtable(clonebuf); + gwbuf_add_to_hashtable(clonebuf); #endif - return clonebuf; - + return clonebuf; } /** @@ -393,50 +388,47 @@ GWBUF *gwbuf_clone_portion( * Return NULL if conversion between types is not supported or due lacking * type information. */ -GWBUF *gwbuf_clone_transform( - GWBUF * head, - gwbuf_type_t targettype) +GWBUF *gwbuf_clone_transform(GWBUF *head, gwbuf_type_t targettype) { - gwbuf_type_t src_type; - GWBUF* clonebuf; - - CHK_GWBUF(head); - src_type = head->gwbuf_type; - - if (targettype == GWBUF_TYPE_UNDEFINED || - src_type == GWBUF_TYPE_UNDEFINED || - src_type == GWBUF_TYPE_PLAINSQL || - targettype == src_type) - { - clonebuf = NULL; - goto return_clonebuf; - } + gwbuf_type_t src_type; + GWBUF* clonebuf; - if (GWBUF_IS_TYPE_MYSQL(head)) + CHK_GWBUF(head); + src_type = head->gwbuf_type; + + if (targettype == GWBUF_TYPE_UNDEFINED || + src_type == GWBUF_TYPE_UNDEFINED || + src_type == GWBUF_TYPE_PLAINSQL || + targettype == src_type) + { + clonebuf = NULL; + goto return_clonebuf; + } + + if (GWBUF_IS_TYPE_MYSQL(head)) + { + if (GWBUF_TYPE_PLAINSQL == targettype) { - if (GWBUF_TYPE_PLAINSQL == targettype) - { - /** Crete reference to string part of buffer */ - clonebuf = gwbuf_clone_portion( - head, - 5, - GWBUF_LENGTH(head)-5); - ss_dassert(clonebuf != NULL); - /** Overwrite the type with new format */ - gwbuf_set_type(clonebuf, targettype); - } - else - { - clonebuf = NULL; - } + /** Crete reference to string part of buffer */ + clonebuf = gwbuf_clone_portion(head, + 5, + GWBUF_LENGTH(head) - 5); + ss_dassert(clonebuf != NULL); + /** Overwrite the type with new format */ + gwbuf_set_type(clonebuf, targettype); } else { - clonebuf = NULL; + clonebuf = NULL; } - + } + else + { + clonebuf = NULL; + } + return_clonebuf: - return clonebuf; + return clonebuf; } @@ -446,22 +438,26 @@ return_clonebuf: * This call should be made with the caller holding the lock for the linked * list. * - * @param head The current head of the linked list - * @param tail The new buffer to make the tail of the linked list - * @return The new head of the linked list + * @param head The current head of the linked list + * @param tail The new buffer to make the tail of the linked list + * @return The new head of the linked list */ -GWBUF * +GWBUF * gwbuf_append(GWBUF *head, GWBUF *tail) { - if (!head) - return tail; - if(!tail) - return head; - CHK_GWBUF(head); - head->tail->next = tail; - head->tail = tail->tail; - - return head; + if (!head) + { + return tail; + } + if (!tail) + { + return head; + } + CHK_GWBUF(head); + head->tail->next = tail; + head->tail = tail->tail; + + return head; } /** @@ -476,53 +472,55 @@ gwbuf_append(GWBUF *head, GWBUF *tail) * This call should be made with the caller holding the lock for the linked * list. * - * @param head The head of the linked list - * @param length The amount of data to consume + * @param head The head of the linked list + * @param length The amount of data to consume * @return The head of the linked list */ GWBUF * gwbuf_consume(GWBUF *head, unsigned int length) { -GWBUF *rval = head; + GWBUF *rval = head; - CHK_GWBUF(head); - GWBUF_CONSUME(head, length); CHK_GWBUF(head); - - if (GWBUF_EMPTY(head)) - { - rval = head->next; - if (head->next) - head->next->tail = head->tail; - - gwbuf_free(head); - } + GWBUF_CONSUME(head, length); + CHK_GWBUF(head); - ss_dassert(rval == NULL || (rval->end > rval->start)); - return rval; + if (GWBUF_EMPTY(head)) + { + rval = head->next; + if (head->next) + { + head->next->tail = head->tail; + } + + gwbuf_free(head); + } + + ss_dassert(rval == NULL || (rval->end > rval->start)); + return rval; } /** * Return the number of bytes of data in the linked list. * - * @param head The current head of the linked list + * @param head The current head of the linked list * @return The number of bytes of data in the linked list */ unsigned int gwbuf_length(GWBUF *head) { -int rval = 0; + int rval = 0; - if (head) - { - CHK_GWBUF(head); - } - while (head) - { - rval += GWBUF_LENGTH(head); - head = head->next; - } - return rval; + if (head) + { + CHK_GWBUF(head); + } + while (head) + { + rval += GWBUF_LENGTH(head); + head = head->next; + } + return rval; } /** @@ -532,23 +530,23 @@ int rval = 0; * * This routine assumes the buffer is not part of a chain * - * @param buf The buffer to trim - * @param n_bytes The number of bytes to trim off - * @return The buffer chain or NULL if buffer has <= n_bytes + * @param buf The buffer to trim + * @param n_bytes The number of bytes to trim off + * @return The buffer chain or NULL if buffer has <= n_bytes */ GWBUF * gwbuf_trim(GWBUF *buf, unsigned int n_bytes) { - ss_dassert(buf->next == NULL); + ss_dassert(buf->next == NULL); - if (GWBUF_LENGTH(buf) <= n_bytes) - { - gwbuf_consume(buf, GWBUF_LENGTH(buf)); - return NULL; - } - buf->end = (void *)((char *)buf->end - n_bytes); + if (GWBUF_LENGTH(buf) <= n_bytes) + { + gwbuf_consume(buf, GWBUF_LENGTH(buf)); + return NULL; + } + buf->end = (void *)((char *)buf->end - n_bytes); - return buf; + return buf; } /** @@ -556,24 +554,24 @@ gwbuf_trim(GWBUF *buf, unsigned int n_bytes) * in a list. If the buffer has n_bytes or less then it will be freed and * the next buffer in the list will be returned, or if none, NULL. * - * @param head The buffer to trim - * @param n_bytes The number of bytes to trim off - * @return The buffer chain or NULL if buffer chain now empty + * @param head The buffer to trim + * @param n_bytes The number of bytes to trim off + * @return The buffer chain or NULL if buffer chain now empty */ GWBUF * gwbuf_rtrim(GWBUF *head, unsigned int n_bytes) { -GWBUF *rval = head; - CHK_GWBUF(head); - GWBUF_RTRIM(head, n_bytes); - CHK_GWBUF(head); - - if (GWBUF_EMPTY(head)) - { - rval = head->next; - gwbuf_free(head); - } - return rval; + GWBUF *rval = head; + CHK_GWBUF(head); + GWBUF_RTRIM(head, n_bytes); + CHK_GWBUF(head); + + if (GWBUF_EMPTY(head)) + { + rval = head->next; + gwbuf_free(head); + } + return rval; } /** @@ -581,227 +579,230 @@ GWBUF *rval = head; * * * @param buf The shared buffer * @param type Type to be added - */ + */ void gwbuf_set_type( - GWBUF* buf, - gwbuf_type_t type) + GWBUF* buf, + gwbuf_type_t type) { - /** Set type consistenly to all buffers on the list */ - while (buf != NULL) - { - CHK_GWBUF(buf); - buf->gwbuf_type |= type; - buf=buf->next; - } + /** Set type consistenly to all buffers on the list */ + while (buf != NULL) + { + CHK_GWBUF(buf); + buf->gwbuf_type |= type; + buf=buf->next; + } } /** * Add a buffer object to GWBUF buffer. - * + * * @param buf GWBUF where object is added - * @param id Type identifier for object + * @param id Type identifier for object * @param data Object data * @param donefun_dp Clean-up function to be executed before buffer is freed. */ -void gwbuf_add_buffer_object( - GWBUF* buf, - bufobj_id_t id, - void* data, - void (*donefun_fp)(void *)) +void gwbuf_add_buffer_object(GWBUF* buf, + bufobj_id_t id, + void* data, + void (*donefun_fp)(void *)) { - buffer_object_t** p_b; - buffer_object_t* newb; - - CHK_GWBUF(buf); - newb = (buffer_object_t *)malloc(sizeof(buffer_object_t)); - ss_dassert(newb != NULL); - - if (newb == NULL) - { - char errbuf[STRERROR_BUFLEN]; - MXS_ERROR("Memory allocation failed due to %s.", - strerror_r(errno, errbuf, sizeof(errbuf))); - return; - } - newb->bo_id = id; - newb->bo_data = data; - newb->bo_donefun_fp = donefun_fp; - newb->bo_next = NULL; - /** Lock */ - spinlock_acquire(&buf->gwbuf_lock); - p_b = &buf->gwbuf_bufobj; - /** Search the end of the list and add there */ - while (*p_b != NULL) - { - p_b = &(*p_b)->bo_next; - } - *p_b = newb; - /** Set flag */ - buf->gwbuf_info |= GWBUF_INFO_PARSED; - /** Unlock */ - spinlock_release(&buf->gwbuf_lock); + buffer_object_t** p_b; + buffer_object_t* newb; + + CHK_GWBUF(buf); + newb = (buffer_object_t *)malloc(sizeof(buffer_object_t)); + ss_dassert(newb != NULL); + + if (newb == NULL) + { + char errbuf[STRERROR_BUFLEN]; + MXS_ERROR("Memory allocation failed due to %s.", + strerror_r(errno, errbuf, sizeof(errbuf))); + return; + } + newb->bo_id = id; + newb->bo_data = data; + newb->bo_donefun_fp = donefun_fp; + newb->bo_next = NULL; + /** Lock */ + spinlock_acquire(&buf->gwbuf_lock); + p_b = &buf->gwbuf_bufobj; + /** Search the end of the list and add there */ + while (*p_b != NULL) + { + p_b = &(*p_b)->bo_next; + } + *p_b = newb; + /** Set flag */ + buf->gwbuf_info |= GWBUF_INFO_PARSED; + /** Unlock */ + spinlock_release(&buf->gwbuf_lock); } /** * Search buffer object which matches with the id. - * + * * @param buf GWBUF to be searched * @param id Identifier for the object - * + * * @return Searched buffer object or NULL if not found */ -void* gwbuf_get_buffer_object_data( - GWBUF* buf, - bufobj_id_t id) +void* gwbuf_get_buffer_object_data(GWBUF* buf, bufobj_id_t id) { - buffer_object_t* bo; - - CHK_GWBUF(buf); - /** Lock */ - spinlock_acquire(&buf->gwbuf_lock); - bo = buf->gwbuf_bufobj; - - while (bo != NULL && bo->bo_id != id) - { - bo = bo->bo_next; - } - /** Unlock */ - spinlock_release(&buf->gwbuf_lock); - if(bo){ - return bo->bo_data; - } - return NULL; + buffer_object_t* bo; + + CHK_GWBUF(buf); + /** Lock */ + spinlock_acquire(&buf->gwbuf_lock); + bo = buf->gwbuf_bufobj; + + while (bo != NULL && bo->bo_id != id) + { + bo = bo->bo_next; + } + /** Unlock */ + spinlock_release(&buf->gwbuf_lock); + if(bo){ + return bo->bo_data; + } + return NULL; } /** * @return pointer to next buffer object or NULL */ -static buffer_object_t* gwbuf_remove_buffer_object( - GWBUF* buf, - buffer_object_t* bufobj) +static buffer_object_t* gwbuf_remove_buffer_object(GWBUF* buf, buffer_object_t* bufobj) { - buffer_object_t* next; - - next = bufobj->bo_next; - /** Call corresponding clean-up function to clean buffer object's data */ - bufobj->bo_donefun_fp(bufobj->bo_data); - free(bufobj); - return next; + buffer_object_t* next; + + next = bufobj->bo_next; + /** Call corresponding clean-up function to clean buffer object's data */ + bufobj->bo_donefun_fp(bufobj->bo_data); + free(bufobj); + return next; } - - /** * Add a property to a buffer. * - * @param buf The buffer to add the property to - * @param name The property name - * @param value The property value - * @return Non-zero on success + * @param buf The buffer to add the property to + * @param name The property name + * @param value The property value + * @return Non-zero on success */ int gwbuf_add_property(GWBUF *buf, char *name, char *value) { -BUF_PROPERTY *prop; + BUF_PROPERTY *prop; - if ((prop = malloc(sizeof(BUF_PROPERTY))) == NULL) - { - ss_dassert(prop != NULL); - char errbuf[STRERROR_BUFLEN]; - MXS_ERROR("Memory allocation failed due to %s.", - strerror_r(errno, errbuf, sizeof(errbuf))); - return 0; - } - prop->name = strdup(name); - prop->value = strdup(value); - spinlock_acquire(&buf->gwbuf_lock); - prop->next = buf->properties; - buf->properties = prop; - spinlock_release(&buf->gwbuf_lock); - return 1; + if ((prop = malloc(sizeof(BUF_PROPERTY))) == NULL) + { + ss_dassert(prop != NULL); + char errbuf[STRERROR_BUFLEN]; + MXS_ERROR("Memory allocation failed due to %s.", + strerror_r(errno, errbuf, sizeof(errbuf))); + return 0; + } + prop->name = strdup(name); + prop->value = strdup(value); + spinlock_acquire(&buf->gwbuf_lock); + prop->next = buf->properties; + buf->properties = prop; + spinlock_release(&buf->gwbuf_lock); + return 1; } /** * Return the value of a buffer property - * @param buf The buffer itself - * @param name The name of the property to return + * @param buf The buffer itself + * @param name The name of the property to return * @return The property value or NULL if the property was not found. */ char * gwbuf_get_property(GWBUF *buf, char *name) { -BUF_PROPERTY *prop; + BUF_PROPERTY *prop; - spinlock_acquire(&buf->gwbuf_lock); - prop = buf->properties; - while (prop && strcmp(prop->name, name) != 0) - prop = prop->next; - spinlock_release(&buf->gwbuf_lock); - if (prop) - return prop->value; - return NULL; + spinlock_acquire(&buf->gwbuf_lock); + prop = buf->properties; + while (prop && strcmp(prop->name, name) != 0) + { + prop = prop->next; + } + spinlock_release(&buf->gwbuf_lock); + if (prop) + { + return prop->value; + } + return NULL; } /** * Convert a chain of GWBUF structures into a single GWBUF structure * - * @param orig The chain to convert - * @return The contiguous buffer + * @param orig The chain to convert + * @return The contiguous buffer */ GWBUF * gwbuf_make_contiguous(GWBUF *orig) { -GWBUF *newbuf; -char *ptr; -int len; + GWBUF *newbuf; + char *ptr; + int len; - if(orig == NULL) - return NULL; - if (orig->next == NULL) - return orig; + if (orig == NULL) + { + return NULL; + } + if (orig->next == NULL) + { + return orig; + } - if ((newbuf = gwbuf_alloc(gwbuf_length(orig))) != NULL) - { - newbuf->gwbuf_type = orig->gwbuf_type; - newbuf->hint = hint_dup(orig->hint); - ptr = GWBUF_DATA(newbuf); - - while (orig) - { - len = GWBUF_LENGTH(orig); - memcpy(ptr, GWBUF_DATA(orig), len); - ptr += len; - orig = gwbuf_consume(orig, len); - } - } - return newbuf; + if ((newbuf = gwbuf_alloc(gwbuf_length(orig))) != NULL) + { + newbuf->gwbuf_type = orig->gwbuf_type; + newbuf->hint = hint_dup(orig->hint); + ptr = GWBUF_DATA(newbuf); + + while (orig) + { + len = GWBUF_LENGTH(orig); + memcpy(ptr, GWBUF_DATA(orig), len); + ptr += len; + orig = gwbuf_consume(orig, len); + } + } + return newbuf; } /** * Add hint to a buffer. * - * @param buf The buffer to add the hint to - * @param hint The hint itself - * @return Non-zero on success + * @param buf The buffer to add the hint to + * @param hint The hint itself + * @return Non-zero on success */ int gwbuf_add_hint(GWBUF *buf, HINT *hint) { -HINT *ptr; + HINT *ptr; - spinlock_acquire(&buf->gwbuf_lock); - if (buf->hint) - { - ptr = buf->hint; - while (ptr->next) - ptr = ptr->next; - ptr->next = hint; - } - else - { - buf->hint = hint; - } - spinlock_release(&buf->gwbuf_lock); - return 1; + spinlock_acquire(&buf->gwbuf_lock); + if (buf->hint) + { + ptr = buf->hint; + while (ptr->next) + { + ptr = ptr->next; + } + ptr->next = hint; + } + else + { + buf->hint = hint; + } + spinlock_release(&buf->gwbuf_lock); + return 1; } diff --git a/server/include/buffer.h b/server/include/buffer.h index 0e1b34246..ff166eb81 100644 --- a/server/include/buffer.h +++ b/server/include/buffer.h @@ -34,12 +34,12 @@ * @verbatim * Revision History * - * Date Who Description - * 10/06/2013 Mark Riddoch Initial implementation - * 11/07/2013 Mark Riddoch Addition of reference count in the gwbuf - * 16/07/2013 Massimiliano Pinto Added command type for the queue - * 10/07/2014 Mark Riddoch Addition of hints - * 15/07/2014 Mark Riddoch Added buffer properties + * Date Who Description + * 10/06/2013 Mark Riddoch Initial implementation + * 11/07/2013 Mark Riddoch Addition of reference count in the gwbuf + * 16/07/2013 Massimiliano Pinto Added command type for the queue + * 10/07/2014 Mark Riddoch Addition of hints + * 15/07/2014 Mark Riddoch Added buffer properties * 03/10/2014 Martin Brampton Pointer arithmetic standard conformity * Add more buffer handling macros * Add gwbuf_rtrim (handle chains) @@ -60,22 +60,23 @@ EXTERN_C_BLOCK_BEGIN * contents. This may be added at any point during the processing of the * data, especially in the protocol stage of the processing. */ -typedef struct buf_property { - char *name; - char *value; - struct buf_property *next; +typedef struct buf_property +{ + char *name; + char *value; + struct buf_property *next; } BUF_PROPERTY; -typedef enum +typedef enum { - GWBUF_TYPE_UNDEFINED = 0x00, - GWBUF_TYPE_PLAINSQL = 0x01, - GWBUF_TYPE_MYSQL = 0x02, - GWBUF_TYPE_SINGLE_STMT = 0x04, - GWBUF_TYPE_SESCMD_RESPONSE = 0x08, - GWBUF_TYPE_RESPONSE_END = 0x10, - GWBUF_TYPE_SESCMD = 0x20, - GWBUF_TYPE_HTTP = 0x40 + GWBUF_TYPE_UNDEFINED = 0x00, + GWBUF_TYPE_PLAINSQL = 0x01, + GWBUF_TYPE_MYSQL = 0x02, + GWBUF_TYPE_SINGLE_STMT = 0x04, + GWBUF_TYPE_SESCMD_RESPONSE = 0x08, + GWBUF_TYPE_RESPONSE_END = 0x10, + GWBUF_TYPE_SESCMD = 0x20, + GWBUF_TYPE_HTTP = 0x40 } gwbuf_type_t; #define GWBUF_IS_TYPE_UNDEFINED(b) (b->gwbuf_type == 0) @@ -91,37 +92,39 @@ typedef enum * shared between multiple GWBUF's without the need to make multiple copies * but still maintain separate data pointers. */ -typedef struct { - unsigned char *data; /*< Physical memory that was allocated */ - int refcount; /*< Reference count on the buffer */ +typedef struct +{ + unsigned char *data; /*< Physical memory that was allocated */ + int refcount; /*< Reference count on the buffer */ } SHARED_BUF; typedef enum -{ - GWBUF_INFO_NONE = 0x0, - GWBUF_INFO_PARSED = 0x1 +{ + GWBUF_INFO_NONE = 0x0, + GWBUF_INFO_PARSED = 0x1 } gwbuf_info_t; #define GWBUF_IS_PARSED(b) (b->gwbuf_info & GWBUF_INFO_PARSED) /** - * A structure for cleaning up memory allocations of structures which are + * A structure for cleaning up memory allocations of structures which are * referred to by GWBUF and deallocated in gwbuf_free but GWBUF doesn't * know what they are. * All functions on the list are executed before freeing memory of GWBUF struct. */ -typedef enum +typedef enum { - GWBUF_PARSING_INFO + GWBUF_PARSING_INFO } bufobj_id_t; typedef struct buffer_object_st buffer_object_t; -struct buffer_object_st { - bufobj_id_t bo_id; - void* bo_data; - void (*bo_donefun_fp)(void *); - buffer_object_t* bo_next; +struct buffer_object_st +{ + bufobj_id_t bo_id; + void* bo_data; + void (*bo_donefun_fp)(void *); + buffer_object_t* bo_next; }; @@ -133,28 +136,29 @@ struct buffer_object_st { * flexible data pointers is designed to minimise the need for data to * be copied within the gateway. */ -typedef struct gwbuf { - SPINLOCK gwbuf_lock; - struct gwbuf *next; /*< Next buffer in a linked chain of buffers */ - struct gwbuf *tail; /*< Last buffer in a linked chain of buffers */ - void *start; /*< Start of the valid data */ - void *end; /*< First byte after the valid data */ - SHARED_BUF *sbuf; /*< The shared buffer with the real data */ - buffer_object_t *gwbuf_bufobj; /*< List of objects referred to by GWBUF */ - gwbuf_info_t gwbuf_info; /*< Info bits */ - gwbuf_type_t gwbuf_type; /*< buffer's data type information */ - HINT *hint; /*< Hint data for this buffer */ - BUF_PROPERTY *properties; /*< Buffer properties */ +typedef struct gwbuf +{ + SPINLOCK gwbuf_lock; + struct gwbuf *next; /*< Next buffer in a linked chain of buffers */ + struct gwbuf *tail; /*< Last buffer in a linked chain of buffers */ + void *start; /*< Start of the valid data */ + void *end; /*< First byte after the valid data */ + SHARED_BUF *sbuf; /*< The shared buffer with the real data */ + buffer_object_t *gwbuf_bufobj; /*< List of objects referred to by GWBUF */ + gwbuf_info_t gwbuf_info; /*< Info bits */ + gwbuf_type_t gwbuf_type; /*< buffer's data type information */ + HINT *hint; /*< Hint data for this buffer */ + BUF_PROPERTY *properties; /*< Buffer properties */ } GWBUF; /*< * Macros to access the data in the buffers */ /*< First valid, unconsumed byte in the buffer */ -#define GWBUF_DATA(b) ((b)->start) +#define GWBUF_DATA(b) ((b)->start) /*< Number of bytes in the individual buffer */ -#define GWBUF_LENGTH(b) ((char *)(b)->end - (char *)(b)->start) +#define GWBUF_LENGTH(b) ((char *)(b)->end - (char *)(b)->start) /*< Return the byte at offset byte from the start of the unconsumed portion of the buffer */ #define GWBUF_DATA_CHAR(b, byte) (GWBUF_LENGTH(b) < ((byte)+1) ? -1 : *(((char *)(b)->start)+4)) @@ -163,39 +167,42 @@ typedef struct gwbuf { #define GWBUF_IS_SQL(b) (0x03 == GWBUF_DATA_CHAR(b,4)) /*< True if all bytes in the buffer have been consumed */ -#define GWBUF_EMPTY(b) ((char *)(b)->start >= (char *)(b)->end) +#define GWBUF_EMPTY(b) ((char *)(b)->start >= (char *)(b)->end) /*< Consume a number of bytes in the buffer */ -#define GWBUF_CONSUME(b, bytes) ((b)->start = bytes > ((char *)(b)->end - (char *)(b)->start) ? (b)->end : (void *)((char *)(b)->start + (bytes))); +#define GWBUF_CONSUME(b, bytes) ((b)->start = bytes > ((char *)(b)->end - (char *)(b)->start) ? (b)->end : (void *)((char *)(b)->start + (bytes))); /*< Check if a given pointer is within the buffer */ -#define GWBUF_POINTER_IN_BUFFER (ptr, b) ((char *)(ptr) >= (char *)(b)->start && (char *)(ptr) < (char *)(b)->end) +#define GWBUF_POINTER_IN_BUFFER (ptr, b)\ + ((char *)(ptr) >= (char *)(b)->start && (char *)(ptr) < (char *)(b)->end) /*< Consume a complete buffer */ -#define GWBUF_CONSUME_ALL(b) gwbuf_consume((b), GWBUF_LENGTH((b))) +#define GWBUF_CONSUME_ALL(b) gwbuf_consume((b), GWBUF_LENGTH((b))) -#define GWBUF_RTRIM(b, bytes) ((b)->end = bytes > ((char *)(b)->end - (char *)(b)->start) ? (b)->start : (void *)((char *)(b)->end - (bytes))); +#define GWBUF_RTRIM(b, bytes)\ + ((b)->end = bytes > ((char *)(b)->end - (char *)(b)->start) ? (b)->start : \ + (void *)((char *)(b)->end - (bytes))); #define GWBUF_TYPE(b) (b)->gwbuf_type /*< * Function prototypes for the API to maniplate the buffers */ -extern GWBUF *gwbuf_alloc(unsigned int size); -extern void gwbuf_free(GWBUF *buf); -extern GWBUF *gwbuf_clone(GWBUF *buf); -extern GWBUF *gwbuf_append(GWBUF *head, GWBUF *tail); -extern GWBUF *gwbuf_consume(GWBUF *head, unsigned int length); -extern GWBUF *gwbuf_trim(GWBUF *head, unsigned int length); -extern GWBUF *gwbuf_rtrim(GWBUF *head, unsigned int length); -extern unsigned int gwbuf_length(GWBUF *head); +extern GWBUF *gwbuf_alloc(unsigned int size); +extern void gwbuf_free(GWBUF *buf); +extern GWBUF *gwbuf_clone(GWBUF *buf); +extern GWBUF *gwbuf_append(GWBUF *head, GWBUF *tail); +extern GWBUF *gwbuf_consume(GWBUF *head, unsigned int length); +extern GWBUF *gwbuf_trim(GWBUF *head, unsigned int length); +extern GWBUF *gwbuf_rtrim(GWBUF *head, unsigned int length); +extern unsigned int gwbuf_length(GWBUF *head); 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_all(GWBUF* head); +extern GWBUF *gwbuf_clone_all(GWBUF* head); extern void gwbuf_set_type(GWBUF *head, gwbuf_type_t type); -extern int gwbuf_add_property(GWBUF *buf, char *name, char *value); -extern char *gwbuf_get_property(GWBUF *buf, char *name); -extern GWBUF *gwbuf_make_contiguous(GWBUF *); -extern int gwbuf_add_hint(GWBUF *, HINT *); +extern int gwbuf_add_property(GWBUF *buf, char *name, char *value); +extern char *gwbuf_get_property(GWBUF *buf, char *name); +extern GWBUF *gwbuf_make_contiguous(GWBUF *); +extern int gwbuf_add_hint(GWBUF *, HINT *); void gwbuf_add_buffer_object(GWBUF* buf, bufobj_id_t id,