diff --git a/build_tools/cflags-devmode.xml b/build_tools/cflags-devmode.xml index 9943cc7989..dd8206b3fa 100644 --- a/build_tools/cflags-devmode.xml +++ b/build_tools/cflags-devmode.xml @@ -9,7 +9,6 @@ extended - DEBUG_THREADS extended diff --git a/include/asterisk/lock.h b/include/asterisk/lock.h index 3cf6f16438..18d1505433 100644 --- a/include/asterisk/lock.h +++ b/include/asterisk/lock.h @@ -134,14 +134,15 @@ struct ast_lock_track_flags { */ struct ast_mutex_info { pthread_mutex_t mutex; -#if !defined(DEBUG_THREADS) && !defined(DEBUG_THREADS_LOOSE_ABI) +#if !defined(DEBUG_THREADS) && !defined(DEBUG_THREADS_LOOSE_ABI) && \ + !defined(DETECT_DEADLOCKS) /*! * These fields are renamed to ensure they are never used when * DEBUG_THREADS is not defined. */ struct ast_lock_track *_track; struct ast_lock_track_flags _flags; -#elif defined(DEBUG_THREADS) +#elif defined(DEBUG_THREADS) || defined(DETECT_DEADLOCKS) /*! Track which thread holds this mutex. */ struct ast_lock_track *track; struct ast_lock_track_flags flags; @@ -155,14 +156,15 @@ struct ast_mutex_info { */ struct ast_rwlock_info { pthread_rwlock_t lock; -#if !defined(DEBUG_THREADS) && !defined(DEBUG_THREADS_LOOSE_ABI) +#if !defined(DEBUG_THREADS) && !defined(DEBUG_THREADS_LOOSE_ABI) && \ + !defined(DETECT_DEADLOCKS) /*! * These fields are renamed to ensure they are never used when * DEBUG_THREADS is not defined. */ struct ast_lock_track *_track; struct ast_lock_track_flags _flags; -#elif defined(DEBUG_THREADS) +#elif defined(DEBUG_THREADS) || defined(DETECT_DEADLOCKS) /*! Track which thread holds this lock */ struct ast_lock_track *track; struct ast_lock_track_flags flags; diff --git a/main/lock.c b/main/lock.c index 8d09f00520..e5be2516db 100644 --- a/main/lock.c +++ b/main/lock.c @@ -54,7 +54,7 @@ static void __attribute__((constructor)) __mtx_init(void) #undef pthread_cond_wait #undef pthread_cond_timedwait -#if defined(DEBUG_THREADS) +#if defined(DEBUG_THREADS) || defined(DETECT_DEADLOCKS) #define log_mutex_error(canlog, ...) \ do { \ if (canlog) { \ @@ -148,8 +148,8 @@ int __ast_pthread_mutex_init(int tracking, const char *filename, int lineno, con int res; pthread_mutexattr_t attr; -#ifdef DEBUG_THREADS -#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) && defined(CAN_COMPARE_MUTEX_TO_INIT_VALUE) +#if defined(DEBUG_THREADS) && defined(AST_MUTEX_INIT_W_CONSTRUCTORS) && \ + defined(CAN_COMPARE_MUTEX_TO_INIT_VALUE) if ((t->mutex) != ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) { int canlog = tracking && strcmp(filename, "logger.c"); @@ -160,6 +160,7 @@ int __ast_pthread_mutex_init(int tracking, const char *filename, int lineno, con } #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ +#if defined(DEBUG_THREADS) || defined(DETECT_DEADLOCKS) t->track = NULL; t->flags.tracking = tracking; t->flags.setup = 0; @@ -256,9 +257,12 @@ int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func, { int res; +#if defined(DETECT_DEADLOCKS) || defined(DEBUG_THREADS) + int canlog = t->flags.tracking && strcmp(filename, "logger.c"); +#endif + #ifdef DEBUG_THREADS struct ast_lock_track *lt = ast_get_reentrancy(&t->track, &t->flags, 0); - int canlog = t->flags.tracking && strcmp(filename, "logger.c"); struct ast_bt *bt = NULL; if (lt) { @@ -281,7 +285,7 @@ int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func, } #endif /* DEBUG_THREADS */ -#if defined(DETECT_DEADLOCKS) && defined(DEBUG_THREADS) +#if defined(DETECT_DEADLOCKS) { time_t seconds = time(NULL); time_t wait_time, reported_wait = 0; @@ -298,6 +302,7 @@ int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func, if (wait_time > reported_wait && (wait_time % 5) == 0) { log_mutex_error(canlog, "%s line %d (%s): Deadlock? waited %d sec for mutex '%s'?\n", filename, lineno, func, (int) wait_time, mutex_name); +#ifdef DEBUG_THREADS if (lt) { ast_reentrancy_lock(lt); #ifdef HAVE_BKTR @@ -311,6 +316,7 @@ int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func, #endif ast_reentrancy_unlock(lt); } +#endif reported_wait = wait_time; if ((int) wait_time < 10) { /* Only emit an event when a deadlock starts, not every 5 seconds */ /*** DOCUMENTATION @@ -687,13 +693,14 @@ int __ast_cond_timedwait(const char *filename, int lineno, const char *func, return res; } -int __ast_rwlock_init(int tracking, const char *filename, int lineno, const char *func, const char *rwlock_name, ast_rwlock_t *t) +int __ast_rwlock_init(int tracking, const char *filename, int lineno, \ + const char *func, const char *rwlock_name, ast_rwlock_t *t) { int res; pthread_rwlockattr_t attr; -#ifdef DEBUG_THREADS -#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) && defined(CAN_COMPARE_MUTEX_TO_INIT_VALUE) +#if defined(DEBUG_THREADS) && defined(AST_MUTEX_INIT_W_CONSTRUCTORS) && \ + defined(CAN_COMPARE_MUTEX_TO_INIT_VALUE) if (t->lock != ((pthread_rwlock_t) __AST_RWLOCK_INIT_VALUE)) { int canlog = tracking && strcmp(filename, "logger.c"); @@ -704,6 +711,7 @@ int __ast_rwlock_init(int tracking, const char *filename, int lineno, const char } #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ +#if defined(DEBUG_THREADS) || defined(DETECT_DEADLOCKS) t->track = NULL; t->flags.tracking = tracking; t->flags.setup = 0; @@ -837,13 +845,17 @@ int __ast_rwlock_unlock(const char *filename, int line, const char *func, ast_rw return res; } -int __ast_rwlock_rdlock(const char *filename, int line, const char *func, ast_rwlock_t *t, const char *name) +int __ast_rwlock_rdlock(const char *filename, int line, const char *func, + ast_rwlock_t *t, const char *name) { int res; +#if defined(DEBUG_THREADS) || defined(DETECT_DEADLOCKS) + int canlog = t->flags.tracking && strcmp(filename, "logger.c"); +#endif + #ifdef DEBUG_THREADS struct ast_lock_track *lt = ast_get_reentrancy(&t->track, &t->flags, 0); - int canlog = t->flags.tracking && strcmp(filename, "logger.c"); struct ast_bt *bt = NULL; if (lt) { @@ -866,7 +878,7 @@ int __ast_rwlock_rdlock(const char *filename, int line, const char *func, ast_rw } #endif /* DEBUG_THREADS */ -#if defined(DETECT_DEADLOCKS) && defined(DEBUG_THREADS) +#if defined(DETECT_DEADLOCKS) { time_t seconds = time(NULL); time_t wait_time, reported_wait = 0; @@ -877,6 +889,7 @@ int __ast_rwlock_rdlock(const char *filename, int line, const char *func, ast_rw if (wait_time > reported_wait && (wait_time % 5) == 0) { log_mutex_error(canlog, "%s line %d (%s): Deadlock? waited %d sec for readlock '%s'?\n", filename, line, func, (int)wait_time, name); +#ifdef DEBUG_THREADS if (lt) { ast_reentrancy_lock(lt); #ifdef HAVE_BKTR @@ -890,15 +903,16 @@ int __ast_rwlock_rdlock(const char *filename, int line, const char *func, ast_rw #endif ast_reentrancy_unlock(lt); } +#endif reported_wait = wait_time; } usleep(200); } } while (res == EBUSY); } -#else /* !DETECT_DEADLOCKS || !DEBUG_THREADS */ +#else /* !DETECT_DEADLOCKS */ res = pthread_rwlock_rdlock(&t->lock); -#endif /* !DETECT_DEADLOCKS || !DEBUG_THREADS */ +#endif /* !DETECT_DEADLOCKS */ #ifdef DEBUG_THREADS if (!res && lt) { @@ -935,13 +949,17 @@ int __ast_rwlock_rdlock(const char *filename, int line, const char *func, ast_rw return res; } -int __ast_rwlock_wrlock(const char *filename, int line, const char *func, ast_rwlock_t *t, const char *name) +int __ast_rwlock_wrlock(const char *filename, int line, const char *func, \ + ast_rwlock_t *t, const char *name) { int res; +#if defined(DEBUG_THREADS) || defined(DETECT_DEADLOCKS) + int canlog = t->flags.tracking && strcmp(filename, "logger.c"); +#endif + #ifdef DEBUG_THREADS struct ast_lock_track *lt = ast_get_reentrancy(&t->track, &t->flags, 0); - int canlog = t->flags.tracking && strcmp(filename, "logger.c"); struct ast_bt *bt = NULL; if (lt) { @@ -964,7 +982,7 @@ int __ast_rwlock_wrlock(const char *filename, int line, const char *func, ast_rw } #endif /* DEBUG_THREADS */ -#if defined(DETECT_DEADLOCKS) && defined(DEBUG_THREADS) +#ifdef DETECT_DEADLOCKS { time_t seconds = time(NULL); time_t wait_time, reported_wait = 0; @@ -975,6 +993,7 @@ int __ast_rwlock_wrlock(const char *filename, int line, const char *func, ast_rw if (wait_time > reported_wait && (wait_time % 5) == 0) { log_mutex_error(canlog, "%s line %d (%s): Deadlock? waited %d sec for writelock '%s'?\n", filename, line, func, (int)wait_time, name); +#ifdef DEBUG_THREADS if (lt) { ast_reentrancy_lock(lt); #ifdef HAVE_BKTR @@ -988,15 +1007,16 @@ int __ast_rwlock_wrlock(const char *filename, int line, const char *func, ast_rw #endif ast_reentrancy_unlock(lt); } +#endif reported_wait = wait_time; } usleep(200); } } while (res == EBUSY); } -#else /* !DETECT_DEADLOCKS || !DEBUG_THREADS */ +#else /* !DETECT_DEADLOCKS */ res = pthread_rwlock_wrlock(&t->lock); -#endif /* !DETECT_DEADLOCKS || !DEBUG_THREADS */ +#endif /* !DETECT_DEADLOCKS */ #ifdef DEBUG_THREADS if (!res && lt) {