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 11c69660 authored by rswindell's avatar rswindell

Implement recursive list locking for non-thread-safe builds (probably not to be

used).
listFreeNods() now locks the list.
parent fae8ce1c
......@@ -54,7 +54,7 @@
link_list_t* DLLCALL listInit(link_list_t* list, long flags)
{
if(flags&LINK_LIST_MALLOC || list==NULL) {
if((flags&LINK_LIST_MALLOC) || list==NULL) {
if((list=(link_list_t*)malloc(sizeof(link_list_t)))==NULL)
return(NULL);
flags |= LINK_LIST_MALLOC;
......@@ -92,12 +92,17 @@ long DLLCALL listFreeNodes(link_list_t* list)
list_node_t* node;
list_node_t* next;
if(list==NULL)
return(-1);
MUTEX_LOCK(list);
for(node=list->first; node!=NULL; node=next) {
if(node->flags&LINK_LIST_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))
&& !(list->flags&LINK_LIST_NEVER_FREE))
listFreeNodeData(node);
......@@ -113,6 +118,8 @@ long DLLCALL listFreeNodes(link_list_t* list)
if(!list->count)
list->last = NULL;
MUTEX_UNLOCK(list);
return(list->count);
}
......@@ -228,7 +235,7 @@ BOOL DLLCALL listLock(link_list_t* list)
if(list==NULL)
return(FALSE);
MUTEX_LOCK(list);
list->flags|=LINK_LIST_LOCKED;
list->locks++;
return(TRUE);
}
......@@ -236,14 +243,16 @@ BOOL DLLCALL listIsLocked(const link_list_t* list)
{
if(list==NULL)
return(FALSE);
return((list->flags&LINK_LIST_LOCKED) ? TRUE : FALSE);
return(list->locks > 0 ? TRUE : FALSE);
}
BOOL DLLCALL listUnlock(link_list_t* list)
{
if(list==NULL)
return(FALSE);
list->flags&=~LINK_LIST_LOCKED;
if(list->locks < 1) /* Not locked */
return(FALSE);
list->locks--;
MUTEX_UNLOCK(list);
return(TRUE);
}
......@@ -444,12 +453,12 @@ void* DLLCALL listNodeData(const list_node_t* node)
BOOL DLLCALL listNodeIsLocked(const list_node_t* node)
{
return(node!=NULL && node->flags&LINK_LIST_LOCKED);
return(node!=NULL && (node->flags&LINK_LIST_LOCKED));
}
BOOL DLLCALL listLockNode(list_node_t* node)
{
if(node==NULL || node->flags&LINK_LIST_LOCKED)
if(node==NULL || (node->flags&LINK_LIST_LOCKED))
return(FALSE);
node->flags|=LINK_LIST_LOCKED;
......
......@@ -60,7 +60,7 @@ extern "C" {
#define LINK_LIST_NEVER_FREE (1<<2) /* NEVER free node data (careful of memory leaks!) */
#define LINK_LIST_MUTEX (1<<3) /* Mutex-protected linked-list */
#define LINK_LIST_SEMAPHORE (1<<4) /* Semaphore attached to linked-list */
#define LINK_LIST_LOCKED (1<<5) /* List or Node is locked */
#define LINK_LIST_LOCKED (1<<5) /* Node is locked */
#define LINK_LIST_ATTACH (1<<6) /* Attach during init */
/* in case the default tag type is not sufficient for your needs, you can over-ride */
......@@ -87,6 +87,7 @@ typedef struct link_list {
long count; /* number of nodes in list */
void* private_data; /* for use by the application/caller */
long refs; /* reference counter (attached clients) */
long locks; /* recursive lock counter */
#if defined(LINK_LIST_THREADSAFE)
pthread_mutex_t mutex;
sem_t sem;
......@@ -111,9 +112,11 @@ DLLEXPORT BOOL DLLCALL listSemTryWaitBlock(link_list_t*, unsigned long timeout);
#endif
/* Lock/unlock linked lists (works best for mutex-protected lists) */
/* Locks are recusive (e.g. must call Unlock for each call to Lock */
DLLEXPORT BOOL DLLCALL listLock(link_list_t*);
DLLEXPORT BOOL DLLCALL listIsLocked(const link_list_t*);
DLLEXPORT BOOL DLLCALL listUnlock(link_list_t*);
DLLEXPORT BOOL DLLCALL listIsLocked(const link_list_t*);
#define listForceUnlock(list) while(listUnlock(list)==TRUE)
/* Return count or index of nodes, or -1 on error */
DLLEXPORT long DLLCALL listCountNodes(const link_list_t*);
......@@ -151,7 +154,7 @@ DLLEXPORT list_node_t* DLLCALL listNextNode(const list_node_t*);
DLLEXPORT list_node_t* DLLCALL listPrevNode(const list_node_t*);
DLLEXPORT void* DLLCALL listNodeData(const list_node_t*);
/* Primitive node locking */
/* Primitive node locking (not recursive) */
DLLEXPORT BOOL DLLCALL listLockNode(list_node_t*);
DLLEXPORT BOOL DLLCALL listUnlockNode(list_node_t*);
DLLEXPORT BOOL DLLCALL listNodeIsLocked(const list_node_t*);
......
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