Loading Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -10,7 +10,7 @@ PUB_INC = ./include #=============================================================================== CC ?= gcc OPTIMIZE = -O3 WARN = -Wall -Wextra -pedantic WARN = -Wall -Wextra -Wstrict-prototypes -Wcast-align -pedantic CDEFS += -D_POSIX_C_SOURCE=1 -D_C99_SOURCE=1 CFLAGS += -std=c99 -fPIC -g $(WARN) $(CDEFS) $(OPTIMIZE) LDFLAGS += -lm -l crypto -l ssl -l pthread Loading config/project.yml +5 −1 Original line number Diff line number Diff line Loading @@ -88,6 +88,8 @@ - -g - -Wall - -Wextra - -Wstrict-prototypes - -Wcast-align - -pedantic - -D_POSIX_C_SOURCE=1 - -D_C99_SOURCE=1 Loading @@ -103,7 +105,9 @@ - -g - -Wall - -Wextra - -pedantic # - -pedantic - -Wstrict-prototypes # - -Wcast-align - -D_POSIX_C_SOURCE=1 - -D_C99_SOURCE=1 - -Wno-nonnull Loading include/kinetic_types.h +10 −1 Original line number Diff line number Diff line Loading @@ -157,7 +157,16 @@ typedef enum { const char* Kinetic_GetStatusDescription(KineticStatus status); typedef void (*KineticCompletionCallback)(KineticStatus status); typedef struct _KineticCompletionData { KineticStatus status; } KineticCompletionData; typedef void (*KineticCompletionCallback)(KineticCompletionData* kinetic_data, void* client_data); typedef struct _KineticCompletionClosure { KineticCompletionCallback callback; void* clientData; } KineticCompletionClosure; // KineticEntry - byte arrays need to be preallocated by the client typedef struct _KineticEntry { Loading src/lib/kinetic_allocator.c +189 −84 Original line number Diff line number Diff line Loading @@ -23,26 +23,59 @@ #include <stdlib.h> #include <pthread.h> static inline void KineticAllocator_LockList(KineticList* const list) //============================================================================== // Generic List Support (INTERNAL) //============================================================================== #define KINETIC_LIST_LOCK(_list) { \ /*LOG_LOCATION; LOGF3("Locking list! (list_addr=0x%llX)", (_list));*/ \ assert(!((_list)->locked)); \ pthread_mutex_lock(&((_list)->mutex)); \ ((_list)->locked) = true; \ } #define KINETIC_LIST_UNLOCK(_list) { \ /*LOG_LOCATION; LOGF3("Unlocking list! (list_addr=0x%llX)", (_list));*/ \ assert(((_list)->locked)); \ pthread_mutex_unlock(&((_list)->mutex)); \ ((_list)->locked) = false; \ } void KineticAllocator_InitLists(KineticConnection* connection) { assert(!list->locked); pthread_mutex_lock(&list->mutex); list->locked = true; assert(connection != NULL); connection->pdus = KINETIC_LIST_INITIALIZER; connection->operations = KINETIC_LIST_INITIALIZER; } static inline void KineticAllocator_UnlockList(KineticList* const list) static void* KineticAllocator_GetFirstListItem(KineticList* list) { // assert(list->locked); pthread_mutex_unlock(&list->mutex); list->locked = false; assert(list != NULL); if (list->start == NULL) { return NULL; } return list->start->data; } void KineticAllocator_InitList(KineticList* const list) static void* KineticAllocator_GetNextListItem(KineticList* list, void* item_data) { *list = (KineticList) { .mutex = PTHREAD_MUTEX_INITIALIZER, .locked = false, }; assert(list != NULL); void* nextData = NULL; KINETIC_LIST_LOCK(list); KineticListItem* current = list->start; while (current != NULL) { void* currData = current->data; if (currData == item_data) { if (current->next != NULL) { nextData = current->next->data; } break; } current = current->next; } KINETIC_LIST_UNLOCK(list); return nextData; } static void* KineticAllocator_NewItem(KineticList* const list, size_t size) Loading @@ -61,7 +94,7 @@ static void* KineticAllocator_NewItem(KineticList* const list, size_t size) memset(newItem->data, 0, size); // Add the new item to the list KineticAllocator_LockList(list); KINETIC_LIST_LOCK(list); if (list->start == NULL) { list->start = newItem; } Loading @@ -70,9 +103,9 @@ static void* KineticAllocator_NewItem(KineticList* const list, size_t size) list->last->next = newItem; } list->last = newItem; KineticAllocator_UnlockList(list); KINETIC_LIST_UNLOCK(list); LOGF3("Allocated new list item @ 0x%0llX w/data @ 0x%0llX", LOGF3(" Allocated new list item (0x%0llX) w/data (0x%0llX)", (long long)newItem, (long long)newItem->data); return newItem->data; Loading @@ -80,12 +113,12 @@ static void* KineticAllocator_NewItem(KineticList* const list, size_t size) static void KineticAllocator_FreeItem(KineticList* const list, void* item) { KineticAllocator_LockList(list); KINETIC_LIST_LOCK(list); KineticListItem* cur = list->start; while (cur->data != item) { if (cur->next == NULL) { LOG1(" Reached end of list before finding item to free!"); KineticAllocator_UnlockList(list); KINETIC_LIST_UNLOCK(list); return; } else { Loading Loading @@ -117,13 +150,13 @@ static void KineticAllocator_FreeItem(KineticList* const list, void* item) if (cur->previous->next != NULL) { LOG3(" Relinking previous to next"); if (cur->next != NULL) { LOG3(" next being reset!"); LOG3(" Next being reset!"); cur->previous->next = cur->next; } else { list->last = cur->previous; list->last->next = NULL; LOGF3(" next is NULL. End of list now @ 0x%0llX", LOGF3(" Next is NULL. End of list now @ 0x%0llX", (long long)list->last); } } Loading @@ -133,21 +166,20 @@ static void KineticAllocator_FreeItem(KineticList* const list, void* item) } } LOGF3(" Freeing item @ 0x%0llX, item @ 0x%0llX", (long long)cur, (long long)&cur->data); LOGF3(" Freeing item (0x%0llX) w/data (0x%0llX)", cur, &cur->data); free(cur->data); cur->data = NULL; free(cur); cur = NULL; } KineticAllocator_UnlockList(list); KINETIC_LIST_UNLOCK(list); } static void KineticAllocator_FreeList(KineticList* const list) { if (list != NULL) { LOG3("Freeing list of all items"); KineticAllocator_LockList(list); LOGF3(" Freeing list (0x%0llX) of all items...", list); KINETIC_LIST_LOCK(list); KineticListItem* current = list->start; while (current->next != NULL) { Loading @@ -156,119 +188,192 @@ static void KineticAllocator_FreeList(KineticList* const list) } while (current != NULL) { LOG2(" Current item not freed!"); LOGF3(" DEALLOCATING item: 0x%0llX, data: 0x%llX, prev: 0x%0llX", (long long)current, (long long)¤t->data, (long long)current->previous); KineticListItem* curItem = current; KineticListItem* prevItem = current->previous; if (curItem != NULL) { LOG3(" Freeing list item"); LOGF3(" Freeing list item (0x%0llX) w/ data (0x%llX)", (long long)current, (long long)¤t->data, (long long)current->previous); if (curItem->data != NULL) { free(curItem->data); } free(curItem); } current = prevItem; LOGF3(" on to prev=0x%llX", (long long)current); LOGF3(" on to previous list item (0x%llX)...", current); } *list = (KineticList) { .start = NULL, .last = NULL }; KineticAllocator_UnlockList(list); // Make list empty, but leave mutex alone so the state is retained! list->start = NULL; list->last = NULL; KINETIC_LIST_UNLOCK(list); } else { LOG1(" Nothing to free!"); LOGF3(" Nothing to free from list (0x%0llX)", list); } } KineticPDU* KineticAllocator_NewPDU(KineticList* const list, KineticConnection* connection) //============================================================================== // PDU List Support //============================================================================== KineticPDU* KineticAllocator_NewPDU(KineticConnection* connection) { assert(connection != NULL); LOGF3("Allocating new PDU on connection (0x%0llX)", connection); KineticPDU* newPDU = (KineticPDU*)KineticAllocator_NewItem( list, sizeof(KineticPDU)); &connection->pdus, sizeof(KineticPDU)); if (newPDU == NULL) { LOG0("Failed allocating new PDU!"); return NULL; } assert(newPDU->proto == NULL); KINETIC_PDU_INIT(newPDU, connection); LOGF3("Allocated new PDU @ 0x%0llX", (long long)newPDU); LOGF3("Allocated new PDU (0x%0llX) on connection", newPDU, connection); return newPDU; } void KineticAllocator_FreePDU(KineticList* const list, KineticPDU* pdu) void KineticAllocator_FreePDU(KineticConnection* connection, KineticPDU* pdu) { KineticAllocator_LockList(list); LOGF3("Freeing PDU (0x%0llX) on connection (0x%0llX)", pdu, connection); KINETIC_LIST_LOCK(&connection->pdus); if ((pdu->proto != NULL) && pdu->protobufDynamicallyExtracted) { LOG3("Freeing dynamically allocated protobuf"); KineticProto_Message__free_unpacked(pdu->proto, NULL); }; KineticAllocator_UnlockList(list); KineticAllocator_FreeItem(list, (void*)pdu); KINETIC_LIST_UNLOCK(&connection->pdus); KineticAllocator_FreeItem(&connection->pdus, (void*)pdu); LOGF3("Freed PDU (0x%0llX) on connection (0x%0llX)", pdu, connection); } KineticPDU* KineticAllocator_GetFirstPDU(KineticList* const list) KineticPDU* KineticAllocator_GetFirstPDU(KineticConnection* connection) { assert(list != NULL); if (list->start == NULL) { return NULL; } return (KineticPDU*)list->start->data; assert(connection != NULL); return (KineticPDU*)KineticAllocator_GetFirstListItem(&connection->pdus); } KineticPDU* KineticAllocator_GetNextPDU(KineticList* const list, KineticPDU* pdu) KineticPDU* KineticAllocator_GetNextPDU(KineticConnection* connection, KineticPDU* pdu) { assert(list != NULL); KineticPDU* next = NULL; assert(connection != NULL); return (KineticPDU*)KineticAllocator_GetNextListItem(&connection->pdus, pdu); } KineticAllocator_LockList(list); KineticListItem* current = list->start; void KineticAllocator_FreeAllPDUs(KineticConnection* connection) { assert(connection != NULL); if (connection->pdus.start != NULL) { LOG3("Freeing all PDUs..."); KINETIC_LIST_LOCK(&connection->pdus); KineticListItem* current = connection->pdus.start; while (current != NULL) { KineticPDU* currPDU = (KineticPDU*)current->data; if (currPDU == pdu) { if (current->next != NULL) { next = (KineticPDU*)current->next->data; } break; KineticPDU* pdu = (KineticPDU*)current->data; if (pdu != NULL && pdu->proto != NULL && pdu->protobufDynamicallyExtracted) { KineticProto_Message__free_unpacked(pdu->proto, NULL); } current = current->next; } KineticAllocator_UnlockList(list); KINETIC_LIST_UNLOCK(&connection->pdus); KineticAllocator_FreeList(&connection->pdus); } else { LOG1(" Nothing to free!"); } } return next; //============================================================================== // Operation List Support //============================================================================== KineticOperation* KineticAllocator_NewOperation(KineticConnection* const connection) { assert(connection != NULL); LOGF3("Allocating new operation on connection (0x%0llX)", connection); KineticOperation* newOperation = (KineticOperation*)KineticAllocator_NewItem(&connection->operations, sizeof(KineticOperation)); if (newOperation == NULL) { LOGF0("Failed allocating new operation on connection (0x%0llX)!", connection); return NULL; } KINETIC_OPERATION_INIT(newOperation, connection); newOperation->request = KineticAllocator_NewPDU(connection); KINETIC_PDU_INIT_WITH_COMMAND(newOperation->request, connection); LOGF3("Allocated new operation (0x%0llX) on connection (0x%0llX)", newOperation, connection); return newOperation; } void KineticAllocator_FreeAllPDUs(KineticList* const list) void KineticAllocator_FreeOperation(KineticConnection* const connection, KineticOperation* operation) { if (list->start != NULL) { LOG3("Freeing all PDUs..."); KineticAllocator_LockList(list); KineticListItem* current = list->start; assert(connection != NULL); assert(operation != NULL); LOGF3("Freeing operation (0x%0llX) on connection (0x%0llX)", operation, connection); if (operation->request != NULL) { LOGF3("Freeing request PDU (0x%0llX) from operation (0x%0llX) on connection (0x%0llX)", operation->request, operation, connection); KineticAllocator_FreePDU(connection, operation->request); } if (operation->response != NULL) { LOGF3("Freeing response PDU (0x%0llX) from operation (0x%0llX) on connection (0x%0llX)", operation->response, operation, connection); KineticAllocator_FreePDU(connection, operation->response); } KineticAllocator_FreeItem(&connection->operations, (void*)operation); LOGF3("Freed operation (0x%0llX) on connection (0x%0llX)", operation, connection); } KineticOperation* KineticAllocator_GetFirstOperation(KineticConnection* const connection) { assert(connection != NULL); return (KineticOperation*)KineticAllocator_GetFirstListItem(&connection->operations); } KineticOperation* KineticAllocator_GetNextOperation(KineticConnection* const connection, KineticOperation* operation) { assert(connection != NULL); return (KineticOperation*)KineticAllocator_GetNextListItem(&connection->operations, operation); } void KineticAllocator_FreeAllOperations(KineticConnection* const connection) { assert(connection != NULL); if (connection->operations.start != NULL) { LOGF3("Freeing all operations in list (0x%0llX) from connection (0x%0llX)...", &connection->operations, connection); KINETIC_LIST_LOCK(&connection->operations); KineticListItem* current = connection->operations.start; while (current != NULL) { KineticPDU* pdu = (KineticPDU*)current->data; if (pdu != NULL && pdu->proto != NULL && pdu->protobufDynamicallyExtracted) { KineticProto_Message__free_unpacked(pdu->proto, NULL); KineticOperation* operation = (KineticOperation*)current->data; if (operation->request != NULL) { KineticAllocator_FreePDU(connection, operation->request); } if (operation->response != NULL) { KineticAllocator_FreePDU(connection, operation->response); } current = current->next; } KineticAllocator_UnlockList(list); KineticAllocator_FreeList(list); KINETIC_LIST_UNLOCK(&connection->operations); KineticAllocator_FreeList(&connection->operations); } else { LOG1(" Nothing to free!"); } } bool KineticAllocator_ValidateAllMemoryFreed(KineticList* const list) bool KineticAllocator_ValidateAllMemoryFreed(KineticConnection* const connection) { bool empty = (list->start == NULL); LOGF3(" PDUList: 0x%0llX, empty=%s", (long long)list->start, empty ? "true" : "false"); assert(connection != NULL); LOGF3("Checking to see if all memory has been freed from connection (0x%0llX)...", connection); bool empty = true; LOGF3(" Operations: 0x%0llX, empty=%s",connection->operations.start, BOOL_TO_STRING(connection->operations.start == NULL)); if (connection->operations.start != NULL) {empty = false;} LOGF3(" PDUs: 0x%0llX, empty=%s", connection->pdus.start, BOOL_TO_STRING(connection->pdus.start == NULL)); if (connection->pdus.start != NULL) {empty = false;} return empty; } src/lib/kinetic_allocator.h +15 −7 Original line number Diff line number Diff line Loading @@ -23,12 +23,20 @@ #include "kinetic_types_internal.h" void KineticAllocator_InitList(KineticList* const list); KineticPDU* KineticAllocator_NewPDU(KineticList* const list, KineticConnection* connection); void KineticAllocator_FreePDU(KineticList* const list, KineticPDU* pdu); KineticPDU* KineticAllocator_GetFirstPDU(KineticList* const list); KineticPDU* KineticAllocator_GetNextPDU(KineticList* const list, KineticPDU* pdu); void KineticAllocator_FreeAllPDUs(KineticList* const list); bool KineticAllocator_ValidateAllMemoryFreed(KineticList* const list); void KineticAllocator_InitLists(KineticConnection* connection); KineticPDU* KineticAllocator_NewPDU(KineticConnection* connection); void KineticAllocator_FreePDU(KineticConnection* connection, KineticPDU* pdu); KineticPDU* KineticAllocator_GetFirstPDU(KineticConnection* connection); KineticPDU* KineticAllocator_GetNextPDU(KineticConnection* connection, KineticPDU* pdu); void KineticAllocator_FreeAllPDUs(KineticConnection* connection); KineticOperation* KineticAllocator_NewOperation(KineticConnection* connection); void KineticAllocator_FreeOperation(KineticConnection* connection, KineticOperation* operation); KineticOperation* KineticAllocator_GetFirstOperation(KineticConnection* connection); KineticOperation* KineticAllocator_GetNextOperation(KineticConnection* connection, KineticOperation* operation); void KineticAllocator_FreeAllOperations(KineticConnection* connection); bool KineticAllocator_ValidateAllMemoryFreed(KineticConnection* connection); #endif // _KINETIC_ALLOCATOR Loading
Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -10,7 +10,7 @@ PUB_INC = ./include #=============================================================================== CC ?= gcc OPTIMIZE = -O3 WARN = -Wall -Wextra -pedantic WARN = -Wall -Wextra -Wstrict-prototypes -Wcast-align -pedantic CDEFS += -D_POSIX_C_SOURCE=1 -D_C99_SOURCE=1 CFLAGS += -std=c99 -fPIC -g $(WARN) $(CDEFS) $(OPTIMIZE) LDFLAGS += -lm -l crypto -l ssl -l pthread Loading
config/project.yml +5 −1 Original line number Diff line number Diff line Loading @@ -88,6 +88,8 @@ - -g - -Wall - -Wextra - -Wstrict-prototypes - -Wcast-align - -pedantic - -D_POSIX_C_SOURCE=1 - -D_C99_SOURCE=1 Loading @@ -103,7 +105,9 @@ - -g - -Wall - -Wextra - -pedantic # - -pedantic - -Wstrict-prototypes # - -Wcast-align - -D_POSIX_C_SOURCE=1 - -D_C99_SOURCE=1 - -Wno-nonnull Loading
include/kinetic_types.h +10 −1 Original line number Diff line number Diff line Loading @@ -157,7 +157,16 @@ typedef enum { const char* Kinetic_GetStatusDescription(KineticStatus status); typedef void (*KineticCompletionCallback)(KineticStatus status); typedef struct _KineticCompletionData { KineticStatus status; } KineticCompletionData; typedef void (*KineticCompletionCallback)(KineticCompletionData* kinetic_data, void* client_data); typedef struct _KineticCompletionClosure { KineticCompletionCallback callback; void* clientData; } KineticCompletionClosure; // KineticEntry - byte arrays need to be preallocated by the client typedef struct _KineticEntry { Loading
src/lib/kinetic_allocator.c +189 −84 Original line number Diff line number Diff line Loading @@ -23,26 +23,59 @@ #include <stdlib.h> #include <pthread.h> static inline void KineticAllocator_LockList(KineticList* const list) //============================================================================== // Generic List Support (INTERNAL) //============================================================================== #define KINETIC_LIST_LOCK(_list) { \ /*LOG_LOCATION; LOGF3("Locking list! (list_addr=0x%llX)", (_list));*/ \ assert(!((_list)->locked)); \ pthread_mutex_lock(&((_list)->mutex)); \ ((_list)->locked) = true; \ } #define KINETIC_LIST_UNLOCK(_list) { \ /*LOG_LOCATION; LOGF3("Unlocking list! (list_addr=0x%llX)", (_list));*/ \ assert(((_list)->locked)); \ pthread_mutex_unlock(&((_list)->mutex)); \ ((_list)->locked) = false; \ } void KineticAllocator_InitLists(KineticConnection* connection) { assert(!list->locked); pthread_mutex_lock(&list->mutex); list->locked = true; assert(connection != NULL); connection->pdus = KINETIC_LIST_INITIALIZER; connection->operations = KINETIC_LIST_INITIALIZER; } static inline void KineticAllocator_UnlockList(KineticList* const list) static void* KineticAllocator_GetFirstListItem(KineticList* list) { // assert(list->locked); pthread_mutex_unlock(&list->mutex); list->locked = false; assert(list != NULL); if (list->start == NULL) { return NULL; } return list->start->data; } void KineticAllocator_InitList(KineticList* const list) static void* KineticAllocator_GetNextListItem(KineticList* list, void* item_data) { *list = (KineticList) { .mutex = PTHREAD_MUTEX_INITIALIZER, .locked = false, }; assert(list != NULL); void* nextData = NULL; KINETIC_LIST_LOCK(list); KineticListItem* current = list->start; while (current != NULL) { void* currData = current->data; if (currData == item_data) { if (current->next != NULL) { nextData = current->next->data; } break; } current = current->next; } KINETIC_LIST_UNLOCK(list); return nextData; } static void* KineticAllocator_NewItem(KineticList* const list, size_t size) Loading @@ -61,7 +94,7 @@ static void* KineticAllocator_NewItem(KineticList* const list, size_t size) memset(newItem->data, 0, size); // Add the new item to the list KineticAllocator_LockList(list); KINETIC_LIST_LOCK(list); if (list->start == NULL) { list->start = newItem; } Loading @@ -70,9 +103,9 @@ static void* KineticAllocator_NewItem(KineticList* const list, size_t size) list->last->next = newItem; } list->last = newItem; KineticAllocator_UnlockList(list); KINETIC_LIST_UNLOCK(list); LOGF3("Allocated new list item @ 0x%0llX w/data @ 0x%0llX", LOGF3(" Allocated new list item (0x%0llX) w/data (0x%0llX)", (long long)newItem, (long long)newItem->data); return newItem->data; Loading @@ -80,12 +113,12 @@ static void* KineticAllocator_NewItem(KineticList* const list, size_t size) static void KineticAllocator_FreeItem(KineticList* const list, void* item) { KineticAllocator_LockList(list); KINETIC_LIST_LOCK(list); KineticListItem* cur = list->start; while (cur->data != item) { if (cur->next == NULL) { LOG1(" Reached end of list before finding item to free!"); KineticAllocator_UnlockList(list); KINETIC_LIST_UNLOCK(list); return; } else { Loading Loading @@ -117,13 +150,13 @@ static void KineticAllocator_FreeItem(KineticList* const list, void* item) if (cur->previous->next != NULL) { LOG3(" Relinking previous to next"); if (cur->next != NULL) { LOG3(" next being reset!"); LOG3(" Next being reset!"); cur->previous->next = cur->next; } else { list->last = cur->previous; list->last->next = NULL; LOGF3(" next is NULL. End of list now @ 0x%0llX", LOGF3(" Next is NULL. End of list now @ 0x%0llX", (long long)list->last); } } Loading @@ -133,21 +166,20 @@ static void KineticAllocator_FreeItem(KineticList* const list, void* item) } } LOGF3(" Freeing item @ 0x%0llX, item @ 0x%0llX", (long long)cur, (long long)&cur->data); LOGF3(" Freeing item (0x%0llX) w/data (0x%0llX)", cur, &cur->data); free(cur->data); cur->data = NULL; free(cur); cur = NULL; } KineticAllocator_UnlockList(list); KINETIC_LIST_UNLOCK(list); } static void KineticAllocator_FreeList(KineticList* const list) { if (list != NULL) { LOG3("Freeing list of all items"); KineticAllocator_LockList(list); LOGF3(" Freeing list (0x%0llX) of all items...", list); KINETIC_LIST_LOCK(list); KineticListItem* current = list->start; while (current->next != NULL) { Loading @@ -156,119 +188,192 @@ static void KineticAllocator_FreeList(KineticList* const list) } while (current != NULL) { LOG2(" Current item not freed!"); LOGF3(" DEALLOCATING item: 0x%0llX, data: 0x%llX, prev: 0x%0llX", (long long)current, (long long)¤t->data, (long long)current->previous); KineticListItem* curItem = current; KineticListItem* prevItem = current->previous; if (curItem != NULL) { LOG3(" Freeing list item"); LOGF3(" Freeing list item (0x%0llX) w/ data (0x%llX)", (long long)current, (long long)¤t->data, (long long)current->previous); if (curItem->data != NULL) { free(curItem->data); } free(curItem); } current = prevItem; LOGF3(" on to prev=0x%llX", (long long)current); LOGF3(" on to previous list item (0x%llX)...", current); } *list = (KineticList) { .start = NULL, .last = NULL }; KineticAllocator_UnlockList(list); // Make list empty, but leave mutex alone so the state is retained! list->start = NULL; list->last = NULL; KINETIC_LIST_UNLOCK(list); } else { LOG1(" Nothing to free!"); LOGF3(" Nothing to free from list (0x%0llX)", list); } } KineticPDU* KineticAllocator_NewPDU(KineticList* const list, KineticConnection* connection) //============================================================================== // PDU List Support //============================================================================== KineticPDU* KineticAllocator_NewPDU(KineticConnection* connection) { assert(connection != NULL); LOGF3("Allocating new PDU on connection (0x%0llX)", connection); KineticPDU* newPDU = (KineticPDU*)KineticAllocator_NewItem( list, sizeof(KineticPDU)); &connection->pdus, sizeof(KineticPDU)); if (newPDU == NULL) { LOG0("Failed allocating new PDU!"); return NULL; } assert(newPDU->proto == NULL); KINETIC_PDU_INIT(newPDU, connection); LOGF3("Allocated new PDU @ 0x%0llX", (long long)newPDU); LOGF3("Allocated new PDU (0x%0llX) on connection", newPDU, connection); return newPDU; } void KineticAllocator_FreePDU(KineticList* const list, KineticPDU* pdu) void KineticAllocator_FreePDU(KineticConnection* connection, KineticPDU* pdu) { KineticAllocator_LockList(list); LOGF3("Freeing PDU (0x%0llX) on connection (0x%0llX)", pdu, connection); KINETIC_LIST_LOCK(&connection->pdus); if ((pdu->proto != NULL) && pdu->protobufDynamicallyExtracted) { LOG3("Freeing dynamically allocated protobuf"); KineticProto_Message__free_unpacked(pdu->proto, NULL); }; KineticAllocator_UnlockList(list); KineticAllocator_FreeItem(list, (void*)pdu); KINETIC_LIST_UNLOCK(&connection->pdus); KineticAllocator_FreeItem(&connection->pdus, (void*)pdu); LOGF3("Freed PDU (0x%0llX) on connection (0x%0llX)", pdu, connection); } KineticPDU* KineticAllocator_GetFirstPDU(KineticList* const list) KineticPDU* KineticAllocator_GetFirstPDU(KineticConnection* connection) { assert(list != NULL); if (list->start == NULL) { return NULL; } return (KineticPDU*)list->start->data; assert(connection != NULL); return (KineticPDU*)KineticAllocator_GetFirstListItem(&connection->pdus); } KineticPDU* KineticAllocator_GetNextPDU(KineticList* const list, KineticPDU* pdu) KineticPDU* KineticAllocator_GetNextPDU(KineticConnection* connection, KineticPDU* pdu) { assert(list != NULL); KineticPDU* next = NULL; assert(connection != NULL); return (KineticPDU*)KineticAllocator_GetNextListItem(&connection->pdus, pdu); } KineticAllocator_LockList(list); KineticListItem* current = list->start; void KineticAllocator_FreeAllPDUs(KineticConnection* connection) { assert(connection != NULL); if (connection->pdus.start != NULL) { LOG3("Freeing all PDUs..."); KINETIC_LIST_LOCK(&connection->pdus); KineticListItem* current = connection->pdus.start; while (current != NULL) { KineticPDU* currPDU = (KineticPDU*)current->data; if (currPDU == pdu) { if (current->next != NULL) { next = (KineticPDU*)current->next->data; } break; KineticPDU* pdu = (KineticPDU*)current->data; if (pdu != NULL && pdu->proto != NULL && pdu->protobufDynamicallyExtracted) { KineticProto_Message__free_unpacked(pdu->proto, NULL); } current = current->next; } KineticAllocator_UnlockList(list); KINETIC_LIST_UNLOCK(&connection->pdus); KineticAllocator_FreeList(&connection->pdus); } else { LOG1(" Nothing to free!"); } } return next; //============================================================================== // Operation List Support //============================================================================== KineticOperation* KineticAllocator_NewOperation(KineticConnection* const connection) { assert(connection != NULL); LOGF3("Allocating new operation on connection (0x%0llX)", connection); KineticOperation* newOperation = (KineticOperation*)KineticAllocator_NewItem(&connection->operations, sizeof(KineticOperation)); if (newOperation == NULL) { LOGF0("Failed allocating new operation on connection (0x%0llX)!", connection); return NULL; } KINETIC_OPERATION_INIT(newOperation, connection); newOperation->request = KineticAllocator_NewPDU(connection); KINETIC_PDU_INIT_WITH_COMMAND(newOperation->request, connection); LOGF3("Allocated new operation (0x%0llX) on connection (0x%0llX)", newOperation, connection); return newOperation; } void KineticAllocator_FreeAllPDUs(KineticList* const list) void KineticAllocator_FreeOperation(KineticConnection* const connection, KineticOperation* operation) { if (list->start != NULL) { LOG3("Freeing all PDUs..."); KineticAllocator_LockList(list); KineticListItem* current = list->start; assert(connection != NULL); assert(operation != NULL); LOGF3("Freeing operation (0x%0llX) on connection (0x%0llX)", operation, connection); if (operation->request != NULL) { LOGF3("Freeing request PDU (0x%0llX) from operation (0x%0llX) on connection (0x%0llX)", operation->request, operation, connection); KineticAllocator_FreePDU(connection, operation->request); } if (operation->response != NULL) { LOGF3("Freeing response PDU (0x%0llX) from operation (0x%0llX) on connection (0x%0llX)", operation->response, operation, connection); KineticAllocator_FreePDU(connection, operation->response); } KineticAllocator_FreeItem(&connection->operations, (void*)operation); LOGF3("Freed operation (0x%0llX) on connection (0x%0llX)", operation, connection); } KineticOperation* KineticAllocator_GetFirstOperation(KineticConnection* const connection) { assert(connection != NULL); return (KineticOperation*)KineticAllocator_GetFirstListItem(&connection->operations); } KineticOperation* KineticAllocator_GetNextOperation(KineticConnection* const connection, KineticOperation* operation) { assert(connection != NULL); return (KineticOperation*)KineticAllocator_GetNextListItem(&connection->operations, operation); } void KineticAllocator_FreeAllOperations(KineticConnection* const connection) { assert(connection != NULL); if (connection->operations.start != NULL) { LOGF3("Freeing all operations in list (0x%0llX) from connection (0x%0llX)...", &connection->operations, connection); KINETIC_LIST_LOCK(&connection->operations); KineticListItem* current = connection->operations.start; while (current != NULL) { KineticPDU* pdu = (KineticPDU*)current->data; if (pdu != NULL && pdu->proto != NULL && pdu->protobufDynamicallyExtracted) { KineticProto_Message__free_unpacked(pdu->proto, NULL); KineticOperation* operation = (KineticOperation*)current->data; if (operation->request != NULL) { KineticAllocator_FreePDU(connection, operation->request); } if (operation->response != NULL) { KineticAllocator_FreePDU(connection, operation->response); } current = current->next; } KineticAllocator_UnlockList(list); KineticAllocator_FreeList(list); KINETIC_LIST_UNLOCK(&connection->operations); KineticAllocator_FreeList(&connection->operations); } else { LOG1(" Nothing to free!"); } } bool KineticAllocator_ValidateAllMemoryFreed(KineticList* const list) bool KineticAllocator_ValidateAllMemoryFreed(KineticConnection* const connection) { bool empty = (list->start == NULL); LOGF3(" PDUList: 0x%0llX, empty=%s", (long long)list->start, empty ? "true" : "false"); assert(connection != NULL); LOGF3("Checking to see if all memory has been freed from connection (0x%0llX)...", connection); bool empty = true; LOGF3(" Operations: 0x%0llX, empty=%s",connection->operations.start, BOOL_TO_STRING(connection->operations.start == NULL)); if (connection->operations.start != NULL) {empty = false;} LOGF3(" PDUs: 0x%0llX, empty=%s", connection->pdus.start, BOOL_TO_STRING(connection->pdus.start == NULL)); if (connection->pdus.start != NULL) {empty = false;} return empty; }
src/lib/kinetic_allocator.h +15 −7 Original line number Diff line number Diff line Loading @@ -23,12 +23,20 @@ #include "kinetic_types_internal.h" void KineticAllocator_InitList(KineticList* const list); KineticPDU* KineticAllocator_NewPDU(KineticList* const list, KineticConnection* connection); void KineticAllocator_FreePDU(KineticList* const list, KineticPDU* pdu); KineticPDU* KineticAllocator_GetFirstPDU(KineticList* const list); KineticPDU* KineticAllocator_GetNextPDU(KineticList* const list, KineticPDU* pdu); void KineticAllocator_FreeAllPDUs(KineticList* const list); bool KineticAllocator_ValidateAllMemoryFreed(KineticList* const list); void KineticAllocator_InitLists(KineticConnection* connection); KineticPDU* KineticAllocator_NewPDU(KineticConnection* connection); void KineticAllocator_FreePDU(KineticConnection* connection, KineticPDU* pdu); KineticPDU* KineticAllocator_GetFirstPDU(KineticConnection* connection); KineticPDU* KineticAllocator_GetNextPDU(KineticConnection* connection, KineticPDU* pdu); void KineticAllocator_FreeAllPDUs(KineticConnection* connection); KineticOperation* KineticAllocator_NewOperation(KineticConnection* connection); void KineticAllocator_FreeOperation(KineticConnection* connection, KineticOperation* operation); KineticOperation* KineticAllocator_GetFirstOperation(KineticConnection* connection); KineticOperation* KineticAllocator_GetNextOperation(KineticConnection* connection, KineticOperation* operation); void KineticAllocator_FreeAllOperations(KineticConnection* connection); bool KineticAllocator_ValidateAllMemoryFreed(KineticConnection* connection); #endif // _KINETIC_ALLOCATOR