#include "capwap.h" #include "capwap_lock.h" #include "capwap_logging.h" #ifndef CAPWAP_MULTITHREADING_ENABLE #error "Warning: multithreading is disabled\n" #endif /* */ int capwap_lock_init(capwap_lock_t* lock) { ASSERT(lock != NULL); memset(lock, 0, sizeof(capwap_lock_t)); if (pthread_mutex_init(&lock->mutex, NULL) != 0) { return 0; } 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) { pthread_mutex_destroy(&lock->mutex); } /* */ void capwap_lock_enter(capwap_lock_t* lock) { pthread_mutex_lock(&lock->mutex); } /* */ void capwap_lock_exit(capwap_lock_t* lock) { pthread_mutex_unlock(&lock->mutex); } #endif