Skip to content
Snippets Groups Projects
Commit 4521d7ea authored by rswindell's avatar rswindell
Browse files

Added support for primitive linked-list node locking.

No longer support NULL data values.
parent 2a0c49a7
No related branches found
No related tags found
No related merge requests found
...@@ -69,55 +69,66 @@ link_list_t* listInit(link_list_t* list, long flags) ...@@ -69,55 +69,66 @@ link_list_t* listInit(link_list_t* list, long flags)
return(list); 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); free(node->data);
node->data = NULL; 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* node;
list_node_t* next; list_node_t* next;
for(node=list->first; node!=NULL; node=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) if(list->flags&LINK_LIST_ALWAYS_FREE || node->flags&LINK_LIST_MALLOC)
listFreeNodeData(node); listFreeNodeData(node);
next = node->next; next = node->next;
free(node); free(node);
if(list->count)
list->count--;
} }
list->first = NULL; list->first = node;
list->last = NULL; if(!list->count)
list->count = 0; list->last = NULL;
return(list->count);
} }
link_list_t* listFree(link_list_t* list) BOOL listFree(link_list_t* list)
{ {
if(list==NULL) if(list==NULL)
return(NULL); return(FALSE);
listFreeNodes(list); if(listFreeNodes(list))
return(FALSE);
MUTEX_DESTROY(list); MUTEX_DESTROY(list);
if(list->flags&LINK_LIST_MALLOC) 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); MUTEX_LOCK(list);
} }
void listUnlock(link_list_t* list) void listUnlock(const link_list_t* list)
{ {
MUTEX_UNLOCK(list); MUTEX_UNLOCK(list);
} }
...@@ -302,6 +313,25 @@ void* listNodeData(const list_node_t* node) ...@@ -302,6 +313,25 @@ void* listNodeData(const list_node_t* node)
return(node->data); 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) static list_node_t* list_add_node(link_list_t* list, list_node_t* node, list_node_t* after)
{ {
if(list==NULL) if(list==NULL)
...@@ -338,7 +368,7 @@ list_node_t* listAddNode(link_list_t* list, void* data, list_node_t* after) ...@@ -338,7 +368,7 @@ list_node_t* listAddNode(link_list_t* list, void* data, list_node_t* after)
{ {
list_node_t* node; list_node_t* node;
if(list==NULL) if(list==NULL || data==NULL)
return(NULL); return(NULL);
if((node=(list_node_t*)malloc(sizeof(list_node_t)))==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) ...@@ -355,7 +385,7 @@ long listAddNodes(link_list_t* list, void** data, list_node_t* after)
if(data==NULL) if(data==NULL)
return(-1); 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) if((node=listAddNode(list,data[i],node==NULL ? after:node))==NULL)
return(i); return(i);
...@@ -412,7 +442,7 @@ long listAddStringList(link_list_t* list, str_list_t str_list, list_node_t* afte ...@@ -412,7 +442,7 @@ long listAddStringList(link_list_t* list, str_list_t str_list, list_node_t* afte
if(str_list==NULL) if(str_list==NULL)
return(-1); 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) if((node=listAddNodeString(list,str_list[i],node==NULL ? after:node))==NULL)
return(i); return(i);
...@@ -484,6 +514,9 @@ void* listRemoveNode(link_list_t* list, list_node_t* node) ...@@ -484,6 +514,9 @@ void* listRemoveNode(link_list_t* list, list_node_t* node)
if(node==NULL) if(node==NULL)
return(NULL); return(NULL);
if(node->flags&LINK_LIST_NODE_LOCKED)
return(NULL);
MUTEX_LOCK(list); MUTEX_LOCK(list);
if(node->prev!=NULL) if(node->prev!=NULL)
...@@ -523,7 +556,8 @@ long listRemoveNodes(link_list_t* list, list_node_t* node, long max) ...@@ -523,7 +556,8 @@ long listRemoveNodes(link_list_t* list, list_node_t* node, long max)
node=list->first; node=list->first;
for(count=0; node!=NULL && count<max; node=node->next, count++) for(count=0; node!=NULL && count<max; node=node->next, count++)
listRemoveNode(list, node); if(listRemoveNode(list, node)==NULL)
break;
MUTEX_UNLOCK(list); MUTEX_UNLOCK(list);
...@@ -542,7 +576,7 @@ int main(int arg, char** argv) ...@@ -542,7 +576,7 @@ int main(int arg, char** argv)
link_list_t list; link_list_t list;
listInit(&list,0); listInit(&list,0);
for(i=0;i<100;i++) { for(i=0; i<100; i++) {
sprintf(str,"%u",i); sprintf(str,"%u",i);
listPushNodeString(&list,str); listPushNodeString(&list,str);
} }
......
...@@ -53,6 +53,7 @@ extern "C" { ...@@ -53,6 +53,7 @@ extern "C" {
#define LINK_LIST_MALLOC (1<<0) /* List/node allocated with malloc() */ #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_ALWAYS_FREE (1<<1) /* Always free node data when removing */
#define LINK_LIST_MUTEX (1<<2) /* Mutex protected linked-list */ #define LINK_LIST_MUTEX (1<<2) /* Mutex protected linked-list */
#define LINK_LIST_NODE_LOCKED (1<<3) /* Node is locked */
typedef struct list_node { typedef struct list_node {
void* data; /* pointer to some kind of data */ void* data; /* pointer to some kind of data */
...@@ -74,13 +75,13 @@ typedef struct link_list { ...@@ -74,13 +75,13 @@ typedef struct link_list {
/* Initialization, Allocation, and Freeing of Lists and Nodes */ /* Initialization, Allocation, and Freeing of Lists and Nodes */
link_list_t* listInit(link_list_t* /* NULL to auto-allocate */, long flags); link_list_t* listInit(link_list_t* /* NULL to auto-allocate */, long flags);
link_list_t* listFree(link_list_t*); BOOL listFree(link_list_t*);
void listFreeNodes(link_list_t*); long listFreeNodes(link_list_t*);
void listFreeNodeData(list_node_t* node); BOOL listFreeNodeData(list_node_t* node);
/* Lock/unlock mutex-protoected linked lists */ /* Lock/unlock mutex-protoected linked lists */
void listLock(link_list_t*); void listLock(const link_list_t*);
void listUnlock(link_list_t*); void listUnlock(const link_list_t*);
/* Return count or index of nodes, or -1 on error */ /* Return count or index of nodes, or -1 on error */
long listCountNodes(const link_list_t*); long listCountNodes(const link_list_t*);
...@@ -107,6 +108,11 @@ list_node_t* listNextNode(const list_node_t*); ...@@ -107,6 +108,11 @@ list_node_t* listNextNode(const list_node_t*);
list_node_t* listPrevNode(const list_node_t*); list_node_t* listPrevNode(const list_node_t*);
void* listNodeData(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 */ /* 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 */); list_node_t* listAddNode(link_list_t*, void* data, list_node_t* after /* NULL=insert */);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment