/************************************************************************ * AUTHOR: NiuJiuRu * FILENAME: swstack.c * DESCRIPTION: 内存栈-先进后出 * NOTE: * HISTORY: * 1, [2014-01-15] created by NiuJiuRu * 2, [2016-08-08] 添加互斥锁, 保障线程安全 ***********************************************************************/ #include "swapi.h" #include "swmutex.h" #include "swmem.h" // node struct stk_node { struct stk_data data; struct stk_node *next; }; // stack struct stk_stack { void *hMem; struct stk_node *top; int nodesCnt; void *hMutex; }; // 创建一个栈, "hMem"为空时在系统内存中创建, "hMem"不为空时在给定的内存中创建 void *sw_stack_create(void *hMem) { struct stk_stack *newStack = NULL; newStack = (struct stk_stack *)(hMem ? sw_mem_alloc(hMem, sizeof(struct stk_stack), __FILE__, __LINE__) : \ malloc(sizeof(struct stk_stack))); if(newStack) { newStack->hMem = hMem; newStack->top = NULL; newStack->nodesCnt = 0; newStack->hMutex = sw_mutex_create(); if(!newStack->hMutex) { newStack->hMem ? sw_mem_free(newStack->hMem, newStack, __FILE__, __LINE__) : free(newStack); return NULL; } } return newStack; } // 数据压栈 bool sw_stack_push(void *hStack, struct stk_data data) { struct stk_stack *theStack = (struct stk_stack *)hStack; struct stk_node *newNode = NULL; if(theStack) { newNode = (struct stk_node *)(theStack->hMem ? sw_mem_alloc(theStack->hMem, sizeof(struct stk_node), __FILE__, __LINE__) : \ malloc(sizeof(struct stk_node))); if(newNode) { newNode->data.addr = data.addr; newNode->data.size = data.size; newNode->data.freeFun = data.freeFun; newNode->data.wParam = data.wParam; newNode->data.lParam = data.lParam; sw_mutex_lock(theStack->hMutex, WAIT_FOREVER); // lock newNode->next = theStack->top; theStack->top = newNode; theStack->nodesCnt += 1; sw_mutex_unlock(theStack->hMutex); // unlock return true; } } return false; } // 数据弹出栈 // 注意: 如果只弹出数据而不接收结果("result"为空时), 弹出过程中将会自动调用数据压栈时设定的内存释放回调函数 void sw_stack_pop(void *hStack, struct stk_data *result) { struct stk_stack *theStack = (struct stk_stack *)hStack; struct stk_node *topNode = NULL; if(theStack && theStack->top) { sw_mutex_lock(theStack->hMutex, WAIT_FOREVER); // lock topNode = theStack->top; theStack->top = theStack->top->next; theStack->nodesCnt -= 1; sw_mutex_unlock(theStack->hMutex); // unlock if(result) { result->addr = topNode->data.addr; result->size = topNode->data.size; result->freeFun = topNode->data.freeFun; result->wParam = topNode->data.wParam; result->lParam = topNode->data.lParam; } else { if(topNode->data.freeFun) topNode->data.freeFun((void *)topNode->data.addr, topNode->data.size); } theStack->hMem ? sw_mem_free(theStack->hMem, topNode, __FILE__, __LINE__) : free(topNode); } } // 得到一个栈内当前的数据元个数 int sw_stack_getDataElementsCnt(const void *hStack) { struct stk_stack *theStack = (struct stk_stack *)hStack; int num; if(theStack) { sw_mutex_lock(theStack->hMutex, WAIT_FOREVER); // lock num = theStack->nodesCnt; sw_mutex_unlock(theStack->hMutex); // unlock } else num = -1; return num; } // 销毁一个栈, 并在销毁过程中自动调用数据压栈时设定的内存释放回调函数 void sw_stack_destroy(void *hStack) { struct stk_stack *theStack = (struct stk_stack *)hStack; struct stk_node *delNode = NULL, *nextNode = NULL; if(theStack) { delNode = theStack->top; while(delNode) { nextNode = delNode->next; if(delNode->data.freeFun) delNode->data.freeFun((void *)delNode->data.addr, delNode->data.size); theStack->hMem ? sw_mem_free(theStack->hMem, delNode, __FILE__, __LINE__) : free(delNode); delNode = nextNode; } sw_mutex_destroy(theStack->hMutex); theStack->hMem ? sw_mem_free(theStack->hMem, theStack, __FILE__, __LINE__) : free(theStack); } }