mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-24 13:13:17 -05:00
consolidate mutex locking to better debug deadlocks
This commit is contained in:
parent
1d1f255a39
commit
cc535d234f
100
src/conf.c
100
src/conf.c
@ -53,6 +53,7 @@
|
|||||||
#include "ll.h"
|
#include "ll.h"
|
||||||
#include "daapd.h"
|
#include "daapd.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
#include "util.h"
|
||||||
#include "webserver.h"
|
#include "webserver.h"
|
||||||
#include "xml-rpc.h"
|
#include "xml-rpc.h"
|
||||||
|
|
||||||
@ -69,7 +70,6 @@ static LL_HANDLE conf_main=NULL;
|
|||||||
static LL_HANDLE conf_comments=NULL;
|
static LL_HANDLE conf_comments=NULL;
|
||||||
|
|
||||||
static char *conf_main_file = NULL;
|
static char *conf_main_file = NULL;
|
||||||
static pthread_mutex_t conf_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
#define CONF_LINEBUFFER 1024
|
#define CONF_LINEBUFFER 1024
|
||||||
|
|
||||||
@ -91,8 +91,6 @@ typedef struct _CONF_ELEMENTS {
|
|||||||
static int _conf_verify(LL_HANDLE pll);
|
static int _conf_verify(LL_HANDLE pll);
|
||||||
static LL_ITEM *_conf_fetch_item(LL_HANDLE pll, char *section, char *key);
|
static LL_ITEM *_conf_fetch_item(LL_HANDLE pll, char *section, char *key);
|
||||||
static int _conf_exists(LL_HANDLE pll, char *section, char *key);
|
static int _conf_exists(LL_HANDLE pll, char *section, char *key);
|
||||||
static void _conf_lock(void);
|
|
||||||
static void _conf_unlock(void);
|
|
||||||
static int _conf_write(FILE *fp, LL *pll, int sublevel, char *parent);
|
static int _conf_write(FILE *fp, LL *pll, int sublevel, char *parent);
|
||||||
static CONF_ELEMENTS *_conf_get_keyinfo(char *section, char *key);
|
static CONF_ELEMENTS *_conf_get_keyinfo(char *section, char *key);
|
||||||
static int _conf_makedir(char *path, char *user);
|
static int _conf_makedir(char *path, char *user);
|
||||||
@ -247,30 +245,6 @@ CONF_ELEMENTS *_conf_get_keyinfo(char *section, char *key) {
|
|||||||
return found ? pcurrent : NULL;
|
return found ? pcurrent : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* lock the conf mutex
|
|
||||||
*/
|
|
||||||
void _conf_lock() {
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if((err=pthread_mutex_lock(&conf_mutex))) {
|
|
||||||
DPRINTF(E_FATAL,L_CONF,"Cannot lock configuration mutex: %s\n",
|
|
||||||
strerror(err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* unlock the conf mutex
|
|
||||||
*/
|
|
||||||
void _conf_unlock() {
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if((err = pthread_mutex_unlock(&conf_mutex))) {
|
|
||||||
DPRINTF(E_FATAL,L_CONF,"Cannot unlock configuration mutex %s\n",
|
|
||||||
strerror(err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fetch item based on section/term basis, rather than just a single
|
* fetch item based on section/term basis, rather than just a single
|
||||||
* level deep, like ll_fetch_item does
|
* level deep, like ll_fetch_item does
|
||||||
@ -850,7 +824,7 @@ int conf_read(char *file) {
|
|||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
if(_conf_verify(pllnew)) {
|
if(_conf_verify(pllnew)) {
|
||||||
DPRINTF(E_INF,L_CONF,"Loading new config file.\n");
|
DPRINTF(E_INF,L_CONF,"Loading new config file.\n");
|
||||||
_conf_lock();
|
util_mutex_lock(l_conf);
|
||||||
_conf_apply(pllnew);
|
_conf_apply(pllnew);
|
||||||
if(conf_main) {
|
if(conf_main) {
|
||||||
ll_destroy(conf_main);
|
ll_destroy(conf_main);
|
||||||
@ -862,7 +836,7 @@ int conf_read(char *file) {
|
|||||||
|
|
||||||
conf_main = pllnew;
|
conf_main = pllnew;
|
||||||
conf_comments = pllcomment;
|
conf_comments = pllcomment;
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
} else {
|
} else {
|
||||||
ll_destroy(pllnew);
|
ll_destroy(pllnew);
|
||||||
ll_destroy(pllcomment);
|
ll_destroy(pllcomment);
|
||||||
@ -908,14 +882,14 @@ int conf_get_int(char *section, char *key, int dflt) {
|
|||||||
LL_ITEM *pitem;
|
LL_ITEM *pitem;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
_conf_lock();
|
util_mutex_lock(l_conf);
|
||||||
pitem = _conf_fetch_item(conf_main,section,key);
|
pitem = _conf_fetch_item(conf_main,section,key);
|
||||||
if((!pitem) || (pitem->type != LL_TYPE_STRING)) {
|
if((!pitem) || (pitem->type != LL_TYPE_STRING)) {
|
||||||
retval = dflt;
|
retval = dflt;
|
||||||
} else {
|
} else {
|
||||||
retval = atoi(pitem->value.as_string);
|
retval = atoi(pitem->value.as_string);
|
||||||
}
|
}
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -936,7 +910,7 @@ int conf_get_string(char *section, char *key, char *dflt, char *out, int *size)
|
|||||||
char *result;
|
char *result;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
_conf_lock();
|
util_mutex_lock(l_conf);
|
||||||
pitem = _conf_fetch_item(conf_main,section,key);
|
pitem = _conf_fetch_item(conf_main,section,key);
|
||||||
if((!pitem) || (pitem->type != LL_TYPE_STRING)) {
|
if((!pitem) || (pitem->type != LL_TYPE_STRING)) {
|
||||||
result = dflt;
|
result = dflt;
|
||||||
@ -945,7 +919,7 @@ int conf_get_string(char *section, char *key, char *dflt, char *out, int *size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!result) {
|
if(!result) {
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return CONF_E_NOTFOUND;
|
return CONF_E_NOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -955,12 +929,12 @@ int conf_get_string(char *section, char *key, char *dflt, char *out, int *size)
|
|||||||
*size = len;
|
*size = len;
|
||||||
strcpy(out,result);
|
strcpy(out,result);
|
||||||
} else {
|
} else {
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
*size = len;
|
*size = len;
|
||||||
return CONF_E_OVERFLOW;
|
return CONF_E_OVERFLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return CONF_E_SUCCESS;
|
return CONF_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -978,7 +952,7 @@ char *conf_alloc_string(char *section, char *key, char *dflt) {
|
|||||||
char *result;
|
char *result;
|
||||||
char *retval;
|
char *retval;
|
||||||
|
|
||||||
_conf_lock();
|
util_mutex_lock(l_conf);
|
||||||
pitem = _conf_fetch_item(conf_main,section,key);
|
pitem = _conf_fetch_item(conf_main,section,key);
|
||||||
if((!pitem) || (pitem->type != LL_TYPE_STRING)) {
|
if((!pitem) || (pitem->type != LL_TYPE_STRING)) {
|
||||||
result = dflt;
|
result = dflt;
|
||||||
@ -987,7 +961,7 @@ char *conf_alloc_string(char *section, char *key, char *dflt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(result == NULL) {
|
if(result == NULL) {
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -996,7 +970,7 @@ char *conf_alloc_string(char *section, char *key, char *dflt) {
|
|||||||
if(!retval) {
|
if(!retval) {
|
||||||
DPRINTF(E_FATAL,L_CONF,"Malloc error in conf_alloc_string\n");
|
DPRINTF(E_FATAL,L_CONF,"Malloc error in conf_alloc_string\n");
|
||||||
}
|
}
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1039,17 +1013,17 @@ int conf_set_string(char *section, char *key, char *value, int verify) {
|
|||||||
char *oldvalue=NULL;
|
char *oldvalue=NULL;
|
||||||
LL_ITEM *polditem;
|
LL_ITEM *polditem;
|
||||||
|
|
||||||
_conf_lock();
|
util_mutex_lock(l_conf);
|
||||||
|
|
||||||
/* verify the item */
|
/* verify the item */
|
||||||
err=_conf_verify_element(section,key,value);
|
err=_conf_verify_element(section,key,value);
|
||||||
if(err != CONF_E_SUCCESS) {
|
if(err != CONF_E_SUCCESS) {
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(verify) {
|
if(verify) {
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return CONF_E_SUCCESS;
|
return CONF_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1070,19 +1044,19 @@ int conf_set_string(char *section, char *key, char *value, int verify) {
|
|||||||
/* deleting the item */
|
/* deleting the item */
|
||||||
pitem = ll_fetch_item(conf_main,section);
|
pitem = ll_fetch_item(conf_main,section);
|
||||||
if(!pitem) {
|
if(!pitem) {
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return CONF_E_SUCCESS;
|
return CONF_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
section_ll = pitem->value.as_ll;
|
section_ll = pitem->value.as_ll;
|
||||||
if(!section_ll) {
|
if(!section_ll) {
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return CONF_E_SUCCESS; /* ?? deleting an already deleted item */
|
return CONF_E_SUCCESS; /* ?? deleting an already deleted item */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* don't care about item... might already be gone! */
|
/* don't care about item... might already be gone! */
|
||||||
ll_del_item(section_ll,key);
|
ll_del_item(section_ll,key);
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return CONF_E_SUCCESS;
|
return CONF_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1093,12 +1067,12 @@ int conf_set_string(char *section, char *key, char *value, int verify) {
|
|||||||
/* that subkey doesn't exist yet... */
|
/* that subkey doesn't exist yet... */
|
||||||
if((err = ll_create(§ion_ll)) != LL_E_SUCCESS) {
|
if((err = ll_create(§ion_ll)) != LL_E_SUCCESS) {
|
||||||
DPRINTF(E_LOG,L_CONF,"Could not create linked list: %d\n",err);
|
DPRINTF(E_LOG,L_CONF,"Could not create linked list: %d\n",err);
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return CONF_E_UNKNOWN;
|
return CONF_E_UNKNOWN;
|
||||||
}
|
}
|
||||||
if((err=ll_add_ll(conf_main,section,section_ll)) != LL_E_SUCCESS) {
|
if((err=ll_add_ll(conf_main,section,section_ll)) != LL_E_SUCCESS) {
|
||||||
DPRINTF(E_LOG,L_CONF,"Error inserting new subkey: %d\n",err);
|
DPRINTF(E_LOG,L_CONF,"Error inserting new subkey: %d\n",err);
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return CONF_E_UNKNOWN;
|
return CONF_E_UNKNOWN;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1123,7 +1097,7 @@ int conf_set_string(char *section, char *key, char *value, int verify) {
|
|||||||
if((err = ll_add_string(section_ll,key,value)) != LL_E_SUCCESS) {
|
if((err = ll_add_string(section_ll,key,value)) != LL_E_SUCCESS) {
|
||||||
DPRINTF(E_LOG,L_CONF,"Error in conf_set_string: "
|
DPRINTF(E_LOG,L_CONF,"Error in conf_set_string: "
|
||||||
"(%s/%s)\n",section,key);
|
"(%s/%s)\n",section,key);
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return CONF_E_UNKNOWN;
|
return CONF_E_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1150,7 +1124,7 @@ int conf_set_string(char *section, char *key, char *value, int verify) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return conf_write();
|
return conf_write();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1163,14 +1137,14 @@ int conf_iswritable(void) {
|
|||||||
int retval = FALSE;
|
int retval = FALSE;
|
||||||
|
|
||||||
/* don't want configfile reopened under us */
|
/* don't want configfile reopened under us */
|
||||||
_conf_lock();
|
util_mutex_lock(l_conf);
|
||||||
|
|
||||||
if(!conf_main_file)
|
if(!conf_main_file)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
retval = !access(conf_main_file,W_OK);
|
retval = !access(conf_main_file,W_OK);
|
||||||
|
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1186,12 +1160,12 @@ int conf_write(void) {
|
|||||||
return CONF_E_NOCONF;
|
return CONF_E_NOCONF;
|
||||||
}
|
}
|
||||||
|
|
||||||
_conf_lock();
|
util_mutex_lock(l_conf);
|
||||||
if((fp = fopen(conf_main_file,"w+")) != NULL) {
|
if((fp = fopen(conf_main_file,"w+")) != NULL) {
|
||||||
retval = _conf_write(fp,conf_main,0,NULL);
|
retval = _conf_write(fp,conf_main,0,NULL);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
|
|
||||||
return retval ? CONF_E_SUCCESS : CONF_E_NOTWRITABLE;
|
return retval ? CONF_E_SUCCESS : CONF_E_NOTWRITABLE;
|
||||||
}
|
}
|
||||||
@ -1302,11 +1276,11 @@ int _conf_write(FILE *fp, LL *pll, int sublevel, char *parent) {
|
|||||||
int conf_isset(char *section, char *key) {
|
int conf_isset(char *section, char *key) {
|
||||||
int retval = FALSE;
|
int retval = FALSE;
|
||||||
|
|
||||||
_conf_lock();
|
util_mutex_lock(l_conf);
|
||||||
if(_conf_fetch_item(conf_main,section,key)) {
|
if(_conf_fetch_item(conf_main,section,key)) {
|
||||||
retval = TRUE;
|
retval = TRUE;
|
||||||
}
|
}
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -1415,10 +1389,10 @@ char *conf_implode(char *section, char *key, char *delimiter) {
|
|||||||
int len;
|
int len;
|
||||||
char *retval;
|
char *retval;
|
||||||
|
|
||||||
_conf_lock();
|
util_mutex_lock(l_conf);
|
||||||
pitem = _conf_fetch_item(conf_main,section,key);
|
pitem = _conf_fetch_item(conf_main,section,key);
|
||||||
if((!pitem) || (pitem->type != LL_TYPE_LL)) {
|
if((!pitem) || (pitem->type != LL_TYPE_LL)) {
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1434,7 +1408,7 @@ char *conf_implode(char *section, char *key, char *delimiter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!count) {
|
if(!count) {
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1453,7 +1427,7 @@ char *conf_implode(char *section, char *key, char *delimiter) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1485,10 +1459,10 @@ int conf_get_array(char *section, char *key, char ***argvp) {
|
|||||||
int count;
|
int count;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
_conf_lock();
|
util_mutex_lock(l_conf);
|
||||||
pitem = _conf_fetch_item(conf_main,section,key);
|
pitem = _conf_fetch_item(conf_main,section,key);
|
||||||
if((!pitem) || (pitem->type != LL_TYPE_LL)) {
|
if((!pitem) || (pitem->type != LL_TYPE_LL)) {
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1521,7 +1495,7 @@ int conf_get_array(char *section, char *key, char ***argvp) {
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1562,11 +1536,11 @@ int conf_xml_dump(WS_CONNINFO *pwsc) {
|
|||||||
pxml = xml_init(pwsc,1);
|
pxml = xml_init(pwsc,1);
|
||||||
xml_push(pxml,"config");
|
xml_push(pxml,"config");
|
||||||
|
|
||||||
_conf_lock();
|
util_mutex_lock(l_conf);
|
||||||
|
|
||||||
retval = _conf_xml_dump(pxml,conf_main,0,NULL);
|
retval = _conf_xml_dump(pxml,conf_main,0,NULL);
|
||||||
|
|
||||||
_conf_unlock();
|
util_mutex_unlock(l_conf);
|
||||||
|
|
||||||
xml_pop(pxml);
|
xml_pop(pxml);
|
||||||
xml_deinit(pxml);
|
xml_deinit(pxml);
|
||||||
|
69
src/err.c
69
src/err.c
@ -63,7 +63,6 @@ static int err_debuglevel=0; /**< current debuglevel, set from command line with
|
|||||||
static int err_logdest=0; /**< current log destination */
|
static int err_logdest=0; /**< current log destination */
|
||||||
static char err_filename[PATH_MAX + 1];
|
static char err_filename[PATH_MAX + 1];
|
||||||
static FILE *err_file=NULL; /**< if logging to file, the handle of that file */
|
static FILE *err_file=NULL; /**< if logging to file, the handle of that file */
|
||||||
static pthread_mutex_t err_mutex=PTHREAD_MUTEX_INITIALIZER; /**< for serializing log messages */
|
|
||||||
static unsigned int err_debugmask=0xFFFFFFFF; /**< modules to debug, see \ref log_categories */
|
static unsigned int err_debugmask=0xFFFFFFFF; /**< modules to debug, see \ref log_categories */
|
||||||
static int err_truncate = 0;
|
static int err_truncate = 0;
|
||||||
static int err_syslog_open = 0;
|
static int err_syslog_open = 0;
|
||||||
@ -78,8 +77,6 @@ static char *err_categorylist[] = {
|
|||||||
* Forwards
|
* Forwards
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int _err_lock(void);
|
|
||||||
static int _err_unlock(void);
|
|
||||||
static uint32_t _err_get_threadid(void);
|
static uint32_t _err_get_threadid(void);
|
||||||
|
|
||||||
|
|
||||||
@ -112,14 +109,12 @@ void err_reopen(void) {
|
|||||||
if(!(err_logdest & LOGDEST_LOGFILE))
|
if(!(err_logdest & LOGDEST_LOGFILE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// _err_lock();
|
|
||||||
fclose(err_file);
|
fclose(err_file);
|
||||||
err_file = fopen(err_filename,"a");
|
err_file = fopen(err_filename,"a");
|
||||||
if(!err_file) {
|
if(!err_file) {
|
||||||
/* what to do when you lose your logging mechanism? Keep
|
/* what to do when you lose your logging mechanism? Keep
|
||||||
* going?
|
* going?
|
||||||
*/
|
*/
|
||||||
_err_unlock();
|
|
||||||
err = errno;
|
err = errno;
|
||||||
err_setdest(err_logdest & (~LOGDEST_LOGFILE));
|
err_setdest(err_logdest & (~LOGDEST_LOGFILE));
|
||||||
err_setdest(err_logdest | LOGDEST_SYSLOG);
|
err_setdest(err_logdest | LOGDEST_SYSLOG);
|
||||||
@ -128,7 +123,7 @@ void err_reopen(void) {
|
|||||||
strerror(err));
|
strerror(err));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// _err_unlock();
|
|
||||||
DPRINTF(E_LOG,L_MISC,"Rotated logs\n");
|
DPRINTF(E_LOG,L_MISC,"Rotated logs\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +157,7 @@ void err_log(int level, unsigned int cat, char *fmt, ...)
|
|||||||
vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
|
vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
_err_lock(); /* atomic file writes */
|
util_mutex_lock(l_err);
|
||||||
|
|
||||||
if((err_logdest & LOGDEST_LOGFILE) && err_file) {
|
if((err_logdest & LOGDEST_LOGFILE) && err_file) {
|
||||||
tt_now=time(NULL);
|
tt_now=time(NULL);
|
||||||
@ -189,7 +184,7 @@ void err_log(int level, unsigned int cat, char *fmt, ...)
|
|||||||
os_syslog(level,errbuf);
|
os_syslog(level,errbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
_err_unlock();
|
util_mutex_unlock(l_err);
|
||||||
|
|
||||||
#ifndef ERR_LEAN
|
#ifndef ERR_LEAN
|
||||||
if(level < 2) { /* only event level fatals and log level */
|
if(level < 2) { /* only event level fatals and log level */
|
||||||
@ -207,9 +202,9 @@ void err_log(int level, unsigned int cat, char *fmt, ...)
|
|||||||
* simple get/set interface to debuglevel to avoid global
|
* simple get/set interface to debuglevel to avoid global
|
||||||
*/
|
*/
|
||||||
void err_setlevel(int level) {
|
void err_setlevel(int level) {
|
||||||
_err_lock();
|
util_mutex_lock(l_err);
|
||||||
err_debuglevel = level;
|
err_debuglevel = level;
|
||||||
_err_unlock();
|
util_mutex_unlock(l_err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -217,9 +212,10 @@ void err_setlevel(int level) {
|
|||||||
*/
|
*/
|
||||||
int err_getlevel(void) {
|
int err_getlevel(void) {
|
||||||
int level;
|
int level;
|
||||||
_err_lock();
|
|
||||||
|
util_mutex_lock(l_err);
|
||||||
level = err_debuglevel;
|
level = err_debuglevel;
|
||||||
_err_unlock();
|
util_mutex_unlock(l_err);
|
||||||
|
|
||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
@ -231,9 +227,9 @@ int err_getlevel(void) {
|
|||||||
int err_getdest(void) {
|
int err_getdest(void) {
|
||||||
int dest;
|
int dest;
|
||||||
|
|
||||||
_err_lock();
|
util_mutex_lock(l_err);
|
||||||
dest=err_logdest;
|
dest=err_logdest;
|
||||||
_err_unlock();
|
util_mutex_unlock(l_err);
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
@ -263,7 +259,6 @@ int err_setlogfile(char *file) {
|
|||||||
if(strcmp(file,err_filename) == 0)
|
if(strcmp(file,err_filename) == 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
*/
|
*/
|
||||||
// _err_lock();
|
|
||||||
|
|
||||||
if(err_file) {
|
if(err_file) {
|
||||||
fclose(err_file);
|
fclose(err_file);
|
||||||
@ -285,7 +280,6 @@ int err_setlogfile(char *file) {
|
|||||||
result=FALSE;
|
result=FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// _err_unlock();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,7 +293,7 @@ void err_setdest(int destination) {
|
|||||||
if(err_logdest == destination)
|
if(err_logdest == destination)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_err_lock();
|
util_mutex_lock(l_err);
|
||||||
if((err_logdest & LOGDEST_LOGFILE) &&
|
if((err_logdest & LOGDEST_LOGFILE) &&
|
||||||
(!(destination & LOGDEST_LOGFILE))) {
|
(!(destination & LOGDEST_LOGFILE))) {
|
||||||
/* used to be logging to file, not any more */
|
/* used to be logging to file, not any more */
|
||||||
@ -307,7 +301,7 @@ void err_setdest(int destination) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
err_logdest=destination;
|
err_logdest=destination;
|
||||||
_err_unlock();
|
util_mutex_unlock(l_err);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Set the debug mask. Given a comma separated list, this walks
|
* Set the debug mask. Given a comma separated list, this walks
|
||||||
@ -327,7 +321,7 @@ extern int err_setdebugmask(char *list) {
|
|||||||
if(!str)
|
if(!str)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
_err_lock();
|
util_mutex_lock(l_err);
|
||||||
while(1) {
|
while(1) {
|
||||||
token=strtok_r(str,",",&last);
|
token=strtok_r(str,",",&last);
|
||||||
str=NULL;
|
str=NULL;
|
||||||
@ -342,7 +336,7 @@ extern int err_setdebugmask(char *list) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!err_categorylist[index]) {
|
if(!err_categorylist[index]) {
|
||||||
_err_unlock();
|
util_mutex_unlock(l_err);
|
||||||
DPRINTF(E_LOG,L_MISC,"Unknown module: %s\n",token);
|
DPRINTF(E_LOG,L_MISC,"Unknown module: %s\n",token);
|
||||||
free(tmpstr);
|
free(tmpstr);
|
||||||
return 1;
|
return 1;
|
||||||
@ -352,44 +346,11 @@ extern int err_setdebugmask(char *list) {
|
|||||||
} else break; /* !token */
|
} else break; /* !token */
|
||||||
}
|
}
|
||||||
|
|
||||||
_err_unlock();
|
util_mutex_unlock(l_err);
|
||||||
DPRINTF(E_INF,L_MISC,"Debug mask is 0x%08x\n",err_debugmask);
|
DPRINTF(E_INF,L_MISC,"Debug mask is 0x%08x\n",err_debugmask);
|
||||||
free(tmpstr);
|
free(tmpstr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Lock the error mutex. This is used to serialize
|
|
||||||
* log messages, as well as protect access to the memory
|
|
||||||
* list, when memory debugging is enabled.
|
|
||||||
*
|
|
||||||
* \returns 0 on success, otherwise -1 with errno set
|
|
||||||
*/
|
|
||||||
int _err_lock(void) {
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if((err=pthread_mutex_lock(&err_mutex))) {
|
|
||||||
errno=err;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unlock the error mutex
|
|
||||||
*
|
|
||||||
* \returns 0 on success, otherwise -1 with errno set
|
|
||||||
*/
|
|
||||||
int _err_unlock(void) {
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if((err=pthread_mutex_unlock(&err_mutex))) {
|
|
||||||
errno=err;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
54
src/util.c
54
src/util.c
@ -6,6 +6,8 @@
|
|||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#ifdef HAVE_STDINT_H
|
#ifdef HAVE_STDINT_H
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
#endif
|
#endif
|
||||||
@ -21,10 +23,16 @@
|
|||||||
#include "err.h"
|
#include "err.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
/* Globals */
|
||||||
|
pthread_mutex_t util_locks[(int)l_last];
|
||||||
|
pthread_mutex_t util_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
int _util_initialized=0;
|
||||||
|
|
||||||
|
|
||||||
/* Forwards */
|
/* Forwards */
|
||||||
//int _util_xtoy(unsigned char *dbuffer, size_t dlen, unsigned char *sbuffer, size_t slen, char *from, char *to);
|
//int _util_xtoy(unsigned char *dbuffer, size_t dlen, unsigned char *sbuffer, size_t slen, char *from, char *to);
|
||||||
void _util_hexdump(unsigned char *block, int len);
|
void _util_hexdump(unsigned char *block, int len);
|
||||||
|
void _util_mutex_init(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple hash generator
|
* Simple hash generator
|
||||||
@ -424,3 +432,47 @@ void _util_hexdump(unsigned char *block, int len) {
|
|||||||
fprintf(stderr,"%s\n",output);
|
fprintf(stderr,"%s\n",output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* simple mutex wrapper for better debugging
|
||||||
|
*/
|
||||||
|
void util_mutex_lock(lock_t which) {
|
||||||
|
if(!_util_initialized)
|
||||||
|
_util_mutex_init();
|
||||||
|
|
||||||
|
pthread_mutex_lock(&util_locks[(int)which]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* simple mutex wrapper for better debugging
|
||||||
|
*/
|
||||||
|
void util_mutex_unlock(lock_t which) {
|
||||||
|
pthread_mutex_unlock(&util_locks[(int)which]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mutex initializer. This might should be done from the
|
||||||
|
* main thread.
|
||||||
|
*/
|
||||||
|
void _util_mutex_init(void) {
|
||||||
|
int err;
|
||||||
|
lock_t lock;
|
||||||
|
|
||||||
|
if((err = pthread_mutex_lock(&util_mutex))) {
|
||||||
|
fprintf(stderr,"Error locking mutex\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!_util_initialized) {
|
||||||
|
/* now, walk through and manually initialize the mutexes */
|
||||||
|
for(lock=(lock_t)0; lock < l_last; lock++) {
|
||||||
|
if((err = pthread_mutex_init(&util_locks[(int)lock],NULL))) {
|
||||||
|
fprintf(stderr,"Error initializing mutex\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_util_initialized=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&util_mutex);
|
||||||
|
}
|
||||||
|
12
src/util.h
12
src/util.h
@ -15,6 +15,18 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
l_err,
|
||||||
|
l_conf,
|
||||||
|
l_plugin,
|
||||||
|
l_last
|
||||||
|
} lock_t;
|
||||||
|
|
||||||
|
/* debugging lock wrappers */
|
||||||
|
|
||||||
|
extern void util_mutex_lock(lock_t which);
|
||||||
|
extern void util_mutex_unlock(lock_t which);
|
||||||
|
|
||||||
/* simple hashing functions */
|
/* simple hashing functions */
|
||||||
extern uint32_t util_djb_hash_block(unsigned char *data, uint32_t len);
|
extern uint32_t util_djb_hash_block(unsigned char *data, uint32_t len);
|
||||||
extern uint32_t util_djb_hash_str(char *str);
|
extern uint32_t util_djb_hash_str(char *str);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user