Add debug information into mutex calls

This commit is contained in:
vemax78 2013-11-10 22:10:40 +01:00
parent bd6e6547b7
commit 5f635602ce
2 changed files with 85 additions and 6 deletions

View File

@ -1,5 +1,6 @@
#include "capwap.h"
#include "capwap_lock.h"
#include "capwap_logging.h"
#ifndef CAPWAP_MULTITHREADING_ENABLE
#error "Warning: multithreading is disabled\n"
@ -17,23 +18,85 @@ int capwap_lock_init(capwap_lock_t* lock) {
return 1;
}
#ifdef DEBUG
/* */
void capwap_lock_destroy_debug(capwap_lock_t* lock, const char* file, const int line) {
int res;
ASSERT(lock != NULL);
res = pthread_mutex_trylock(&lock->mutex);
if (!res) {
pthread_mutex_unlock(&lock->mutex);
} else if (res == EINVAL) {
capwap_logging_debug("Attempt to destroy invalid mutex from '%s' (%d)", file, line);
capwap_backtrace_callstack();
} else if (res == EBUSY) {
capwap_logging_debug("Attempt to destroy locked mutex by '%s' (%d) from '%s' (%d)", lock->file, lock->line, file, line);
capwap_backtrace_callstack();
}
pthread_mutex_destroy(&lock->mutex);
}
/* */
void capwap_lock_enter_debug(capwap_lock_t* lock, const char* file, const int line) {
int res;
time_t starttime;
time_t waittime;
time_t lasttime = 0;
ASSERT(lock != NULL);
/* */
starttime = time(NULL);
do {
res = pthread_mutex_trylock(&lock->mutex);
if (res == EBUSY) {
waittime = time(NULL) - starttime;
if (!(waittime % 5) && (waittime > lasttime)) {
lasttime = waittime;
capwap_logging_debug("Waited %d sec for mutex '%s' (%d) locked by '%s' (%d)", waittime, file, line, lock->file, lock->line);
capwap_backtrace_callstack();
}
usleep(200);
}
} while (res == EBUSY);
/* */
lock->file = (char*)file;
lock->line = (int)line;
}
/* */
void capwap_lock_exit_debug(capwap_lock_t* lock, const char* file, const int line) {
ASSERT(lock != NULL);
/* */
lock->file = NULL;
lock->line = 0;
/* */
if (pthread_mutex_unlock(&lock->mutex)) {
capwap_logging_debug("Error releasing mutex '%s' (%d)", file, line);
capwap_backtrace_callstack();
}
}
#else
/* */
void capwap_lock_destroy(capwap_lock_t* lock) {
ASSERT(lock != NULL);
pthread_mutex_destroy(&lock->mutex);
}
/* */
void capwap_lock_enter(capwap_lock_t* lock) {
ASSERT(lock != NULL);
pthread_mutex_lock(&lock->mutex);
}
/* */
void capwap_lock_exit(capwap_lock_t* lock) {
ASSERT(lock != NULL);
pthread_mutex_unlock(&lock->mutex);
}
#endif

View File

@ -7,12 +7,28 @@
typedef struct {
pthread_mutex_t mutex;
#ifdef DEBUG
char* file;
int line;
#endif
} capwap_lock_t;
int capwap_lock_init(capwap_lock_t* lock);
#ifdef DEBUG
#define capwap_lock_destroy(lock) capwap_lock_destroy_debug(lock, __FILE__, __LINE__)
void capwap_lock_destroy_debug(capwap_lock_t* lock, const char* file, const int line);
#define capwap_lock_enter(lock) capwap_lock_enter_debug(lock, __FILE__, __LINE__)
void capwap_lock_enter_debug(capwap_lock_t* lock, const char* file, const int line);
#define capwap_lock_exit(lock) capwap_lock_exit_debug(lock, __FILE__, __LINE__)
void capwap_lock_exit_debug(capwap_lock_t* lock, const char* file, const int line);
#else
void capwap_lock_destroy(capwap_lock_t* lock);
void capwap_lock_enter(capwap_lock_t* lock);
void capwap_lock_exit(capwap_lock_t* lock);
#endif
#endif /* CAPWAP_MULTITHREADING_ENABLE */