Add debug information into mutex calls
This commit is contained in:
parent
bd6e6547b7
commit
5f635602ce
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user