From 4521d7ea9a157c1e3fef0248610161d1957fce40 Mon Sep 17 00:00:00 2001 From: rswindell <> Date: Fri, 21 May 2004 02:31:33 +0000 Subject: [PATCH] Added support for primitive linked-list node locking. No longer support NULL data values. --- src/xpdev/link_list.c | 70 ++++++++++++++++++++++++++++++++----------- src/xpdev/link_list.h | 16 ++++++---- 2 files changed, 63 insertions(+), 23 deletions(-) diff --git a/src/xpdev/link_list.c b/src/xpdev/link_list.c index bc54490093..80dbbda7a6 100644 --- a/src/xpdev/link_list.c +++ b/src/xpdev/link_list.c @@ -69,55 +69,66 @@ link_list_t* listInit(link_list_t* list, long flags) return(list); } -void listFreeNodeData(list_node_t* node) +BOOL listFreeNodeData(list_node_t* node) { - if(node!=NULL && node->data!=NULL) { + if(node!=NULL && node->data!=NULL && !(node->flags&LINK_LIST_NODE_LOCKED)) { free(node->data); node->data = NULL; + return(TRUE); } + return(FALSE); } -void listFreeNodes(link_list_t* list) +long listFreeNodes(link_list_t* list) { list_node_t* node; list_node_t* next; for(node=list->first; node!=NULL; node=next) { + if(node->flags&LINK_LIST_NODE_LOCKED) + break; + if(list->flags&LINK_LIST_ALWAYS_FREE || node->flags&LINK_LIST_MALLOC) listFreeNodeData(node); next = node->next; free(node); + + if(list->count) + list->count--; } - list->first = NULL; - list->last = NULL; - list->count = 0; + list->first = node; + if(!list->count) + list->last = NULL; + + return(list->count); } -link_list_t* listFree(link_list_t* list) +BOOL listFree(link_list_t* list) { if(list==NULL) - return(NULL); + return(FALSE); - listFreeNodes(list); + if(listFreeNodes(list)) + return(FALSE); MUTEX_DESTROY(list); if(list->flags&LINK_LIST_MALLOC) - free(list), list=NULL; + free(list); - return(list); + return(TRUE); } -void listLock(link_list_t* list) +void listLock(const link_list_t* list) { MUTEX_LOCK(list); } -void listUnlock(link_list_t* list) +void listUnlock(const link_list_t* list) { MUTEX_UNLOCK(list); } @@ -302,6 +313,25 @@ void* listNodeData(const list_node_t* node) return(node->data); } +void listLockNode(list_node_t* node) +{ + if(node!=NULL) + node->flags|=LINK_LIST_NODE_LOCKED; +} + +void listUnlockNode(list_node_t* node) +{ + if(node!=NULL) + node->flags&=~LINK_LIST_NODE_LOCKED; +} + +BOOL listNodeIsLocked(const list_node_t* node) +{ + if(node!=NULL && node->flags&LINK_LIST_NODE_LOCKED) + return(TRUE); + return(FALSE); +} + static list_node_t* list_add_node(link_list_t* list, list_node_t* node, list_node_t* after) { if(list==NULL) @@ -338,7 +368,7 @@ list_node_t* listAddNode(link_list_t* list, void* data, list_node_t* after) { list_node_t* node; - if(list==NULL) + if(list==NULL || data==NULL) return(NULL); if((node=(list_node_t*)malloc(sizeof(list_node_t)))==NULL) @@ -355,7 +385,7 @@ long listAddNodes(link_list_t* list, void** data, list_node_t* after) if(data==NULL) return(-1); - for(i=0;data[i];i++) + for(i=0; data[i]!=NULL ;i++) if((node=listAddNode(list,data[i],node==NULL ? after:node))==NULL) return(i); @@ -412,7 +442,7 @@ long listAddStringList(link_list_t* list, str_list_t str_list, list_node_t* afte if(str_list==NULL) return(-1); - for(i=0;str_list[i];i++) + for(i=0; str_list[i]!=NULL ;i++) if((node=listAddNodeString(list,str_list[i],node==NULL ? after:node))==NULL) return(i); @@ -484,6 +514,9 @@ void* listRemoveNode(link_list_t* list, list_node_t* node) if(node==NULL) return(NULL); + if(node->flags&LINK_LIST_NODE_LOCKED) + return(NULL); + MUTEX_LOCK(list); if(node->prev!=NULL) @@ -523,7 +556,8 @@ long listRemoveNodes(link_list_t* list, list_node_t* node, long max) node=list->first; for(count=0; node!=NULL && count<max; node=node->next, count++) - listRemoveNode(list, node); + if(listRemoveNode(list, node)==NULL) + break; MUTEX_UNLOCK(list); @@ -542,7 +576,7 @@ int main(int arg, char** argv) link_list_t list; listInit(&list,0); - for(i=0;i<100;i++) { + for(i=0; i<100; i++) { sprintf(str,"%u",i); listPushNodeString(&list,str); } diff --git a/src/xpdev/link_list.h b/src/xpdev/link_list.h index 8af8b606c8..73875fe5b8 100644 --- a/src/xpdev/link_list.h +++ b/src/xpdev/link_list.h @@ -53,6 +53,7 @@ extern "C" { #define LINK_LIST_MALLOC (1<<0) /* List/node allocated with malloc() */ #define LINK_LIST_ALWAYS_FREE (1<<1) /* Always free node data when removing */ #define LINK_LIST_MUTEX (1<<2) /* Mutex protected linked-list */ +#define LINK_LIST_NODE_LOCKED (1<<3) /* Node is locked */ typedef struct list_node { void* data; /* pointer to some kind of data */ @@ -74,13 +75,13 @@ typedef struct link_list { /* Initialization, Allocation, and Freeing of Lists and Nodes */ link_list_t* listInit(link_list_t* /* NULL to auto-allocate */, long flags); -link_list_t* listFree(link_list_t*); -void listFreeNodes(link_list_t*); -void listFreeNodeData(list_node_t* node); +BOOL listFree(link_list_t*); +long listFreeNodes(link_list_t*); +BOOL listFreeNodeData(list_node_t* node); /* Lock/unlock mutex-protoected linked lists */ -void listLock(link_list_t*); -void listUnlock(link_list_t*); +void listLock(const link_list_t*); +void listUnlock(const link_list_t*); /* Return count or index of nodes, or -1 on error */ long listCountNodes(const link_list_t*); @@ -107,6 +108,11 @@ list_node_t* listNextNode(const list_node_t*); list_node_t* listPrevNode(const list_node_t*); void* listNodeData(const list_node_t*); +/* Primitive node locking */ +void listLockNode(list_node_t*); +void listUnlockNode(list_node_t*); +BOOL listNodeIsLocked(const list_node_t*); + /* Add node to list, returns pointer to new node or NULL on error */ list_node_t* listAddNode(link_list_t*, void* data, list_node_t* after /* NULL=insert */); -- GitLab