Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commit 4521d7ea authored by rswindell's avatar rswindell

Added support for primitive linked-list node locking.

No longer support NULL data values.
parent 2a0c49a7
......@@ -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);
}
......
......@@ -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 */);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment