Add debug information into mutex calls
This commit is contained in:
parent
bd6e6547b7
commit
5f635602ce
@ -1,5 +1,6 @@
|
|||||||
#include "capwap.h"
|
#include "capwap.h"
|
||||||
#include "capwap_lock.h"
|
#include "capwap_lock.h"
|
||||||
|
#include "capwap_logging.h"
|
||||||
|
|
||||||
#ifndef CAPWAP_MULTITHREADING_ENABLE
|
#ifndef CAPWAP_MULTITHREADING_ENABLE
|
||||||
#error "Warning: multithreading is disabled\n"
|
#error "Warning: multithreading is disabled\n"
|
||||||
@ -17,23 +18,85 @@ int capwap_lock_init(capwap_lock_t* lock) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
/* */
|
/* */
|
||||||
void capwap_lock_destroy(capwap_lock_t* lock) {
|
void capwap_lock_destroy_debug(capwap_lock_t* lock, const char* file, const int line) {
|
||||||
|
int res;
|
||||||
|
|
||||||
ASSERT(lock != NULL);
|
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);
|
pthread_mutex_destroy(&lock->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
void capwap_lock_enter(capwap_lock_t* lock) {
|
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);
|
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) {
|
||||||
|
pthread_mutex_destroy(&lock->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* */
|
||||||
|
void capwap_lock_enter(capwap_lock_t* lock) {
|
||||||
pthread_mutex_lock(&lock->mutex);
|
pthread_mutex_lock(&lock->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
void capwap_lock_exit(capwap_lock_t* lock) {
|
void capwap_lock_exit(capwap_lock_t* lock) {
|
||||||
ASSERT(lock != NULL);
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&lock->mutex);
|
pthread_mutex_unlock(&lock->mutex);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@ -7,12 +7,28 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
|
#ifdef DEBUG
|
||||||
|
char* file;
|
||||||
|
int line;
|
||||||
|
#endif
|
||||||
} capwap_lock_t;
|
} capwap_lock_t;
|
||||||
|
|
||||||
int capwap_lock_init(capwap_lock_t* lock);
|
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_destroy(capwap_lock_t* lock);
|
||||||
void capwap_lock_enter(capwap_lock_t* lock);
|
void capwap_lock_enter(capwap_lock_t* lock);
|
||||||
void capwap_lock_exit(capwap_lock_t* lock);
|
void capwap_lock_exit(capwap_lock_t* lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* CAPWAP_MULTITHREADING_ENABLE */
|
#endif /* CAPWAP_MULTITHREADING_ENABLE */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user