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 7663a119 authored by deuce's avatar deuce

Implement recursive mutexes... this assumes that all 0xff is an invalid

(or at least unusable) pthread_t which is fine on FreeBSD as it's a pointer.

I've left the recursive stuff in with an #ifdef __linux__ wrapper though
it's a Bad Thing.

After I talk to DigitalMan, this may all get ripped out in favour of proper
pthread mutex usage, but I'm not sure why he wants recursive mutexes.
parent 602a95dc
......@@ -42,8 +42,42 @@
#if defined(LINK_LIST_THREADSAFE)
#define MUTEX_DESTROY(list) { if(list->flags&LINK_LIST_MUTEX) { while(pthread_mutex_destroy((pthread_mutex_t*)&list->mutex)==EBUSY) SLEEP(1);} }
#define MUTEX_LOCK(list) { if(list->flags&LINK_LIST_MUTEX) pthread_mutex_lock((pthread_mutex_t*)&list->mutex); }
#define MUTEX_UNLOCK(list) { if(list->flags&LINK_LIST_MUTEX) pthread_mutex_unlock((pthread_mutex_t*)&list->mutex); }
#define MUTEX_LOCK(list) { \
if(list->flags&LINK_LIST_MUTEX) { \
pthread_mutex_lock((pthread_mutex_t*)&list->mmutex); \
if(!pthread_equal(list->tid, pthread_self())) { \
pthread_mutex_lock((pthread_mutex_t*)&list->mutex); \
list->tid = pthread_self(); \
} \
list->locks++; \
pthread_mutex_unlock((pthread_mutex_t*)&list->mmutex); \
} \
}
#define MUTEX_UNLOCK(list) { \
if(list->flags&LINK_LIST_MUTEX) { \
pthread_mutex_lock((pthread_mutex_t*)&list->mmutex); \
if(!pthread_equal(list->tid, pthread_self())) { \
/* ERROR! */ \
fprintf(stderr, "BAD UNLOCK (tid=%08x self=%08x)...\n", list->tid, pthread_self()); \
pthread_mutex_unlock((pthread_mutex_t*)&list->mmutex); \
return FALSE; \
} \
else if(list->locks == 0) { \
fprintf(stderr, "Zero locks!...\n"); \
/* ERROR! */ \
pthread_mutex_unlock((pthread_mutex_t*)&list->mmutex); \
return FALSE; \
} \
else { \
list->locks--; \
if(list->locks == 0) { \
pthread_mutex_unlock((pthread_mutex_t*)&list->mutex); \
memset(&list->tid, 0xff, sizeof(list->tid)); \
} \
} \
pthread_mutex_unlock((pthread_mutex_t*)&list->mmutex); \
} \
}
#else
#define MUTEX_DESTROY(list) (void)list
#define MUTEX_LOCK(list) (void)list
......@@ -68,8 +102,11 @@ link_list_t* DLLCALL listInit(link_list_t* list, long flags)
list->flags = flags;
#if defined(LINK_LIST_THREADSAFE)
if(list->flags&LINK_LIST_MUTEX)
if(list->flags&LINK_LIST_MUTEX) {
list->mmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
list->mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
memset(&list->tid, 0xff, sizeof(list->tid));
}
if(list->flags&LINK_LIST_SEMAPHORE)
sem_init(&list->sem,0,0);
......@@ -239,29 +276,29 @@ BOOL DLLCALL listLock(link_list_t* list)
if(list==NULL)
return(FALSE);
MUTEX_LOCK(list);
list->locks++;
return(TRUE);
}
BOOL DLLCALL listIsLocked(const link_list_t* list)
{
BOOL ret;
if(list==NULL)
return(FALSE);
return(list->locks > 0 ? TRUE : FALSE);
pthread_mutex_lock((pthread_mutex_t*)&list->mmutex);
ret = list->locks > 0 ? TRUE : FALSE;
pthread_mutex_unlock((pthread_mutex_t*)&list->mmutex);
return(ret);
}
BOOL DLLCALL listUnlock(link_list_t* list)
{
if(list==NULL)
return(FALSE);
if(list->locks < 1) /* Not locked */
return(FALSE);
list->locks--;
MUTEX_UNLOCK(list);
return(TRUE);
}
long DLLCALL listCountNodes(const link_list_t* list)
long DLLCALL listCountNodes(link_list_t* list)
{
long count=0;
list_node_t* node;
......@@ -282,7 +319,7 @@ long DLLCALL listCountNodes(const link_list_t* list)
return(count);
}
list_node_t* DLLCALL listFindNode(const link_list_t* list, const void* data, size_t length)
list_node_t* DLLCALL listFindNode(link_list_t* list, const void* data, size_t length)
{
list_node_t* node;
......@@ -307,7 +344,7 @@ list_node_t* DLLCALL listFindNode(const link_list_t* list, const void* data, siz
return(node);
}
str_list_t DLLCALL listStringList(const link_list_t* list)
str_list_t DLLCALL listStringList(link_list_t* list)
{
list_node_t* node;
str_list_t str_list;
......@@ -370,7 +407,7 @@ list_node_t* DLLCALL listFirstNode(const link_list_t* list)
return(list->first);
}
list_node_t* DLLCALL listLastNode(const link_list_t* list)
list_node_t* DLLCALL listLastNode(link_list_t* list)
{
list_node_t* node;
list_node_t* last=NULL;
......@@ -391,7 +428,7 @@ list_node_t* DLLCALL listLastNode(const link_list_t* list)
return(last);
}
long DLLCALL listNodeIndex(const link_list_t* list, list_node_t* find_node)
long DLLCALL listNodeIndex(link_list_t* list, list_node_t* find_node)
{
long i=0;
list_node_t* node;
......@@ -413,7 +450,7 @@ long DLLCALL listNodeIndex(const link_list_t* list, list_node_t* find_node)
return(i);
}
list_node_t* DLLCALL listNodeAt(const link_list_t* list, long index)
list_node_t* DLLCALL listNodeAt(link_list_t* list, long index)
{
long i=0;
list_node_t* node;
......
......@@ -89,7 +89,9 @@ typedef struct link_list {
long refs; /* reference counter (attached clients) */
long locks; /* recursive lock counter */
#if defined(LINK_LIST_THREADSAFE)
pthread_mutex_t mmutex;
pthread_mutex_t mutex;
pthread_t tid;
sem_t sem;
#endif
} link_list_t;
......@@ -119,15 +121,15 @@ 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*);
DLLEXPORT long DLLCALL listNodeIndex(const link_list_t*, list_node_t*);
DLLEXPORT long DLLCALL listCountNodes(link_list_t*);
DLLEXPORT long DLLCALL listNodeIndex(link_list_t*, list_node_t*);
/* Get/Set list private data */
DLLEXPORT void* DLLCALL listSetPrivateData(link_list_t*, void*);
DLLEXPORT void* DLLCALL listGetPrivateData(link_list_t*);
/* Return an allocated string list (which must be freed), array of all strings in linked list */
DLLEXPORT str_list_t DLLCALL listStringList(const link_list_t*);
DLLEXPORT str_list_t DLLCALL listStringList(link_list_t*);
/* Return an allocated string list (which must be freed), subset of strings in linked list */
DLLEXPORT str_list_t DLLCALL listSubStringList(const list_node_t*, long max);
......@@ -140,16 +142,16 @@ DLLEXPORT void* DLLCALL listFreeStringList(str_list_t);
DLLEXPORT link_list_t* DLLCALL listExtract(link_list_t* dest_list, const list_node_t* src_node, long max);
/* Simple search functions returning found node or NULL on error */
DLLEXPORT list_node_t* DLLCALL listNodeAt(const link_list_t*, long index);
DLLEXPORT list_node_t* DLLCALL listNodeAt(link_list_t*, long index);
/* Find a specific node by data */
/* Pass length of 0 to search by data pointer rather than by data content comparison (memcmp) */
DLLEXPORT list_node_t* DLLCALL listFindNode(const link_list_t*, const void* data, size_t length);
DLLEXPORT list_node_t* DLLCALL listFindNode(link_list_t*, const void* data, size_t length);
/* Find a specific node by its tag value */
#define listFindTaggedNode(list, tag) listFindNode(list, NULL, tag)
/* Convenience functions */
DLLEXPORT list_node_t* DLLCALL listFirstNode(const link_list_t*);
DLLEXPORT list_node_t* DLLCALL listLastNode(const link_list_t*);
DLLEXPORT list_node_t* DLLCALL listLastNode(link_list_t*);
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*);
......
......@@ -109,12 +109,14 @@ pthread_mutex_t pthread_mutex_initializer(BOOL recursive);
#define SetThreadName(c)
#endif
#if defined(__linux__)
#if !defined(PTHREAD_MUTEX_RECURSIVE)
#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
#endif
#if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) && !defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
#endif
#endif
#else
......
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