Index: include/asterisk/lock.h =================================================================== --- include/asterisk/lock.h (.../branches/1.8) (revision 303461) +++ include/asterisk/lock.h (.../team/tilghman/issue18194) (revision 303461) @@ -91,11 +91,11 @@ #define AST_LOCK_TRACK_INIT_VALUE { { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INIT_VALUE } #endif -#define AST_MUTEX_INIT_VALUE { AST_LOCK_TRACK_INIT_VALUE, 1, PTHREAD_MUTEX_INIT_VALUE } -#define AST_MUTEX_INIT_VALUE_NOTRACKING { AST_LOCK_TRACK_INIT_VALUE, 0, PTHREAD_MUTEX_INIT_VALUE } +#define AST_MUTEX_INIT_VALUE { PTHREAD_MUTEX_INIT_VALUE, NULL, 1 } +#define AST_MUTEX_INIT_VALUE_NOTRACKING { PTHREAD_MUTEX_INIT_VALUE, NULL, 0 } -#define AST_RWLOCK_INIT_VALUE { AST_LOCK_TRACK_INIT_VALUE, 1, __AST_RWLOCK_INIT_VALUE } -#define AST_RWLOCK_INIT_VALUE_NOTRACKING { AST_LOCK_TRACK_INIT_VALUE, 0, __AST_RWLOCK_INIT_VALUE } +#define AST_RWLOCK_INIT_VALUE { __AST_RWLOCK_INIT_VALUE, NULL, 1 } +#define AST_RWLOCK_INIT_VALUE_NOTRACKING { __AST_RWLOCK_INIT_VALUE, NULL, 0 } #define AST_MAX_REENTRANCY 10 @@ -119,10 +119,10 @@ * The information will just be ignored in the core if a module does not request it.. */ struct ast_mutex_info { + pthread_mutex_t mutex; /*! Track which thread holds this mutex */ - struct ast_lock_track track; + struct ast_lock_track *track; unsigned int tracking:1; - pthread_mutex_t mutex; }; /*! \brief Structure for rwlock and tracking information. @@ -131,10 +131,10 @@ * The information will just be ignored in the core if a module does not request it.. */ struct ast_rwlock_info { + pthread_rwlock_t lock; /*! Track which thread holds this lock */ - struct ast_lock_track track; + struct ast_lock_track *track; unsigned int tracking:1; - pthread_rwlock_t lock; }; typedef struct ast_mutex_info ast_mutex_t; @@ -174,13 +174,13 @@ 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_destroy(const char *filename, int lineno, const char *func, const char *rwlock_name, ast_rwlock_t *t); -int __ast_rwlock_unlock(ast_rwlock_t *t, const char *name, const char *filename, int line, const char *func); -int __ast_rwlock_rdlock(ast_rwlock_t *t, const char *name, const char *filename, int line, const char *func); -int __ast_rwlock_wrlock(ast_rwlock_t *t, const char *name, const char *filename, int line, const char *func); -int __ast_rwlock_timedrdlock(ast_rwlock_t *t, const char *name, const struct timespec *abs_timeout, const char *filename, int line, const char *func); -int __ast_rwlock_timedwrlock(ast_rwlock_t *t, const char *name, const struct timespec *abs_timeout, const char *filename, int line, const char *func); -int __ast_rwlock_tryrdlock(ast_rwlock_t *t, const char *name, const char *filename, int line, const char *func); -int __ast_rwlock_trywrlock(ast_rwlock_t *t, const char *name, const char *filename, int line, const char *func); +int __ast_rwlock_unlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name); +int __ast_rwlock_rdlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name); +int __ast_rwlock_wrlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name); +int __ast_rwlock_timedrdlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name, const struct timespec *abs_timeout); +int __ast_rwlock_timedwrlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name, const struct timespec *abs_timeout); +int __ast_rwlock_tryrdlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name); +int __ast_rwlock_trywrlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name); /*! * \brief wrapper for rwlock with tracking enabled @@ -197,13 +197,13 @@ #define ast_rwlock_init_notracking(rwlock) __ast_rwlock_init(0, __FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock) #define ast_rwlock_destroy(rwlock) __ast_rwlock_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock) -#define ast_rwlock_unlock(a) __ast_rwlock_unlock(a, #a, __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define ast_rwlock_rdlock(a) __ast_rwlock_rdlock(a, #a, __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define ast_rwlock_wrlock(a) __ast_rwlock_wrlock(a, #a, __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define ast_rwlock_tryrdlock(a) __ast_rwlock_tryrdlock(a, #a, __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define ast_rwlock_trywrlock(a) __ast_rwlock_trywrlock(a, #a, __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define ast_rwlock_timedrdlock(a, b) __ast_rwlock_timedrdlock(a, #a, b, __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define ast_rwlock_timedwrlock(a, b) __ast_rwlock_timedwrlock(a, #a, b, __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define ast_rwlock_unlock(a) __ast_rwlock_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a) +#define ast_rwlock_rdlock(a) __ast_rwlock_rdlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a) +#define ast_rwlock_wrlock(a) __ast_rwlock_wrlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a) +#define ast_rwlock_tryrdlock(a) __ast_rwlock_tryrdlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a) +#define ast_rwlock_trywrlock(a) __ast_rwlock_trywrlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a) +#define ast_rwlock_timedrdlock(a, b) __ast_rwlock_timedrdlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a, b) +#define ast_rwlock_timedwrlock(a, b) __ast_rwlock_timedwrlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a, b) #define ROFFSET ((lt->reentrancy > 0) ? (lt->reentrancy-1) : 0) @@ -436,11 +436,16 @@ pthread_mutex_unlock(<->reentr_mutex); } -static inline void ast_reentrancy_init(struct ast_lock_track *lt) +static inline void ast_reentrancy_init(struct ast_lock_track **plt) { int i; pthread_mutexattr_t reentr_attr; + struct ast_lock_track *lt = *plt; + if (!lt) { + lt = *plt = (struct ast_lock_track *) ast_calloc(1, sizeof(*lt)); + } + for (i = 0; i < AST_MAX_REENTRANCY; i++) { lt->file[i] = NULL; lt->lineno[i] = 0; @@ -459,9 +464,15 @@ pthread_mutexattr_destroy(&reentr_attr); } -static inline void delete_reentrancy_cs(struct ast_lock_track *lt) +static inline void delete_reentrancy_cs(struct ast_lock_track **plt) { - pthread_mutex_destroy(<->reentr_mutex); + struct ast_lock_track *lt; + if (*plt) { + lt = *plt; + pthread_mutex_destroy(<->reentr_mutex); + ast_free(lt); + *plt = NULL; + } } #else /* !DEBUG_THREADS */ Index: main/utils.c =================================================================== --- main/utils.c (.../branches/1.8) (revision 303461) +++ main/utils.c (.../team/tilghman/issue18194) (revision 303461) @@ -782,7 +782,7 @@ return; lock = lock_info->locks[i].lock_addr; - lt = &lock->track; + lt = lock->track; ast_reentrancy_lock(lt); for (j = 0; *str && j < lt->reentrancy; j++) { ast_str_append(str, 0, "=== --- ---> Locked Here: %s line %d (%s)\n", Index: main/heap.c =================================================================== --- main/heap.c (.../branches/1.8) (revision 303461) +++ main/heap.c (.../team/tilghman/issue18194) (revision 303461) @@ -308,15 +308,15 @@ int __ast_heap_wrlock(struct ast_heap *h, const char *file, const char *func, int line) { - return __ast_rwlock_wrlock(&h->lock, "&h->lock", file, line, func); + return __ast_rwlock_wrlock(file, line, func, &h->lock, "&h->lock"); } int __ast_heap_rdlock(struct ast_heap *h, const char *file, const char *func, int line) { - return __ast_rwlock_rdlock(&h->lock, "&h->lock", file, line, func); + return __ast_rwlock_rdlock(file, line, func, &h->lock, "&h->lock"); } int __ast_heap_unlock(struct ast_heap *h, const char *file, const char *func, int line) { - return __ast_rwlock_unlock(&h->lock, "&h->lock", file, line, func); + return __ast_rwlock_unlock(file, line, func, &h->lock, "&h->lock"); } Index: main/lock.c =================================================================== --- main/lock.c (.../branches/1.8) (revision 303461) +++ main/lock.c (.../team/tilghman/issue18194) (revision 303461) @@ -62,7 +62,6 @@ #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ ast_reentrancy_init(&t->track); - t->tracking = tracking; #endif /* DEBUG_THREADS */ pthread_mutexattr_init(&attr); @@ -96,7 +95,10 @@ } #endif - lt = &t->track; + if (t->tracking && !t->track) { + ast_reentrancy_init(&t->track); + } + lt = t->track; res = pthread_mutex_trylock(&t->mutex); switch (res) { @@ -110,13 +112,15 @@ case EBUSY: __ast_mutex_logger("%s line %d (%s): Error: attempt to destroy locked mutex '%s'.\n", filename, lineno, func, mutex_name); - ast_reentrancy_lock(lt); - __ast_mutex_logger("%s line %d (%s): Error: '%s' was locked here.\n", - lt->file[ROFFSET], lt->lineno[ROFFSET], lt->func[ROFFSET], mutex_name); + if (t->tracking) { + ast_reentrancy_lock(lt); + __ast_mutex_logger("%s line %d (%s): Error: '%s' was locked here.\n", + lt->file[ROFFSET], lt->lineno[ROFFSET], lt->func[ROFFSET], mutex_name); #ifdef HAVE_BKTR - __dump_backtrace(<->backtrace[ROFFSET], canlog); + __dump_backtrace(<->backtrace[ROFFSET], canlog); #endif - ast_reentrancy_unlock(lt); + ast_reentrancy_unlock(lt); + } break; } #endif /* DEBUG_THREADS */ @@ -128,17 +132,19 @@ __ast_mutex_logger("%s line %d (%s): Error destroying mutex %s: %s\n", filename, lineno, func, mutex_name, strerror(res)); } - ast_reentrancy_lock(lt); - lt->file[0] = filename; - lt->lineno[0] = lineno; - lt->func[0] = func; - lt->reentrancy = 0; - lt->thread[0] = 0; + if (t->tracking) { + ast_reentrancy_lock(lt); + lt->file[0] = filename; + lt->lineno[0] = lineno; + lt->func[0] = func; + lt->reentrancy = 0; + lt->thread[0] = 0; #ifdef HAVE_BKTR - memset(<->backtrace[0], 0, sizeof(lt->backtrace[0])); + memset(<->backtrace[0], 0, sizeof(lt->backtrace[0])); #endif - ast_reentrancy_unlock(lt); - delete_reentrancy_cs(lt); + ast_reentrancy_unlock(lt); + delete_reentrancy_cs(&t->track); + } #endif /* DEBUG_THREADS */ return res; @@ -150,7 +156,7 @@ int res; #ifdef DEBUG_THREADS - struct ast_lock_track *lt = &t->track; + struct ast_lock_track *lt; int canlog = strcmp(filename, "logger.c") & t->tracking; #ifdef HAVE_BKTR struct ast_bt *bt = NULL; @@ -171,6 +177,11 @@ } #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ + if (t->tracking && !t->track) { + ast_reentrancy_init(&t->track); + } + lt = t->track; + if (t->tracking) { #ifdef HAVE_BKTR ast_reentrancy_lock(lt); @@ -231,7 +242,7 @@ #endif /* !DETECT_DEADLOCKS || !DEBUG_THREADS */ #ifdef DEBUG_THREADS - if (!res) { + if (t->tracking && !res) { ast_reentrancy_lock(lt); if (lt->reentrancy < AST_MAX_REENTRANCY) { lt->file[lt->reentrancy] = filename; @@ -247,7 +258,7 @@ if (t->tracking) { ast_mark_lock_acquired(t); } - } else { + } else if (t->tracking) { #ifdef HAVE_BKTR if (lt->reentrancy) { ast_reentrancy_lock(lt); @@ -256,14 +267,12 @@ } else { bt = NULL; } - if (t->tracking) { - ast_remove_lock_info(t, bt); - } + ast_remove_lock_info(t, bt); #else - if (t->tracking) { - ast_remove_lock_info(t); - } + ast_remove_lock_info(t); #endif + } + if (res) { __ast_mutex_logger("%s line %d (%s): Error obtaining mutex: %s\n", filename, lineno, func, strerror(res)); DO_THREAD_CRASH; @@ -279,7 +288,7 @@ int res; #ifdef DEBUG_THREADS - struct ast_lock_track *lt= &t->track; + struct ast_lock_track *lt; int canlog = strcmp(filename, "logger.c") & t->tracking; #ifdef HAVE_BKTR struct ast_bt *bt = NULL; @@ -300,6 +309,11 @@ } #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ + if (t->tracking && !t->track) { + ast_reentrancy_init(&t->track); + } + lt = t->track; + if (t->tracking) { #ifdef HAVE_BKTR ast_reentrancy_lock(lt); @@ -318,7 +332,7 @@ res = pthread_mutex_trylock(&t->mutex); #ifdef DEBUG_THREADS - if (!res) { + if (t->tracking && !res) { ast_reentrancy_lock(lt); if (lt->reentrancy < AST_MAX_REENTRANCY) { lt->file[lt->reentrancy] = filename; @@ -348,7 +362,7 @@ int res; #ifdef DEBUG_THREADS - struct ast_lock_track *lt = &t->track; + struct ast_lock_track *lt; int canlog = strcmp(filename, "logger.c") & t->tracking; #ifdef HAVE_BKTR struct ast_bt *bt = NULL; @@ -367,39 +381,44 @@ } #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ - ast_reentrancy_lock(lt); - if (lt->reentrancy && (lt->thread[ROFFSET] != pthread_self())) { - __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n", - filename, lineno, func, mutex_name); - __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n", - lt->file[ROFFSET], lt->lineno[ROFFSET], lt->func[ROFFSET], mutex_name); + if (t->tracking && !t->track) { + ast_reentrancy_init(&t->track); + } + lt = t->track; + + if (t->tracking) { + ast_reentrancy_lock(lt); + if (lt->reentrancy && (lt->thread[ROFFSET] != pthread_self())) { + __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n", + filename, lineno, func, mutex_name); + __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n", + lt->file[ROFFSET], lt->lineno[ROFFSET], lt->func[ROFFSET], mutex_name); #ifdef HAVE_BKTR - __dump_backtrace(<->backtrace[ROFFSET], canlog); + __dump_backtrace(<->backtrace[ROFFSET], canlog); #endif - DO_THREAD_CRASH; - } + DO_THREAD_CRASH; + } - if (--lt->reentrancy < 0) { - __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n", - filename, lineno, func, mutex_name); - lt->reentrancy = 0; - } + if (--lt->reentrancy < 0) { + __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n", + filename, lineno, func, mutex_name); + lt->reentrancy = 0; + } - if (lt->reentrancy < AST_MAX_REENTRANCY) { - lt->file[lt->reentrancy] = NULL; - lt->lineno[lt->reentrancy] = 0; - lt->func[lt->reentrancy] = NULL; - lt->thread[lt->reentrancy] = 0; - } + if (lt->reentrancy < AST_MAX_REENTRANCY) { + lt->file[lt->reentrancy] = NULL; + lt->lineno[lt->reentrancy] = 0; + lt->func[lt->reentrancy] = NULL; + lt->thread[lt->reentrancy] = 0; + } #ifdef HAVE_BKTR - if (lt->reentrancy) { - bt = <->backtrace[lt->reentrancy - 1]; - } + if (lt->reentrancy) { + bt = <->backtrace[lt->reentrancy - 1]; + } #endif - ast_reentrancy_unlock(lt); + ast_reentrancy_unlock(lt); - if (t->tracking) { #ifdef HAVE_BKTR ast_remove_lock_info(t, bt); #else @@ -453,7 +472,7 @@ int res; #ifdef DEBUG_THREADS - struct ast_lock_track *lt= &t->track; + struct ast_lock_track *lt; int canlog = strcmp(filename, "logger.c") & t->tracking; #ifdef HAVE_BKTR struct ast_bt *bt = NULL; @@ -472,39 +491,44 @@ } #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ - ast_reentrancy_lock(lt); - if (lt->reentrancy && (lt->thread[ROFFSET] != pthread_self())) { - __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n", - filename, lineno, func, mutex_name); - __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n", - lt->file[ROFFSET], lt->lineno[ROFFSET], lt->func[ROFFSET], mutex_name); + if (t->tracking && !t->track) { + ast_reentrancy_init(&t->track); + } + lt = t->track; + + if (t->tracking) { + ast_reentrancy_lock(lt); + if (lt->reentrancy && (lt->thread[ROFFSET] != pthread_self())) { + __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n", + filename, lineno, func, mutex_name); + __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n", + lt->file[ROFFSET], lt->lineno[ROFFSET], lt->func[ROFFSET], mutex_name); #ifdef HAVE_BKTR - __dump_backtrace(<->backtrace[ROFFSET], canlog); + __dump_backtrace(<->backtrace[ROFFSET], canlog); #endif - DO_THREAD_CRASH; - } + DO_THREAD_CRASH; + } - if (--lt->reentrancy < 0) { - __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n", + if (--lt->reentrancy < 0) { + __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n", filename, lineno, func, mutex_name); - lt->reentrancy = 0; - } + lt->reentrancy = 0; + } - if (lt->reentrancy < AST_MAX_REENTRANCY) { - lt->file[lt->reentrancy] = NULL; - lt->lineno[lt->reentrancy] = 0; - lt->func[lt->reentrancy] = NULL; - lt->thread[lt->reentrancy] = 0; - } + if (lt->reentrancy < AST_MAX_REENTRANCY) { + lt->file[lt->reentrancy] = NULL; + lt->lineno[lt->reentrancy] = 0; + lt->func[lt->reentrancy] = NULL; + lt->thread[lt->reentrancy] = 0; + } #ifdef HAVE_BKTR - if (lt->reentrancy) { - bt = <->backtrace[lt->reentrancy - 1]; - } + if (lt->reentrancy) { + bt = <->backtrace[lt->reentrancy - 1]; + } #endif - ast_reentrancy_unlock(lt); + ast_reentrancy_unlock(lt); - if (t->tracking) { #ifdef HAVE_BKTR ast_remove_lock_info(t, bt); #else @@ -520,7 +544,7 @@ __ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n", filename, lineno, func, strerror(res)); DO_THREAD_CRASH; - } else { + } else if (t->tracking) { ast_reentrancy_lock(lt); if (lt->reentrancy < AST_MAX_REENTRANCY) { lt->file[lt->reentrancy] = filename; @@ -538,13 +562,11 @@ } ast_reentrancy_unlock(lt); - if (t->tracking) { #ifdef HAVE_BKTR - ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, t, bt); + ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, t, bt); #else - ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, t); + ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, t); #endif - } } #endif /* DEBUG_THREADS */ @@ -558,7 +580,7 @@ int res; #ifdef DEBUG_THREADS - struct ast_lock_track *lt = &t->track; + struct ast_lock_track *lt; int canlog = strcmp(filename, "logger.c") & t->tracking; #ifdef HAVE_BKTR struct ast_bt *bt = NULL; @@ -577,38 +599,43 @@ } #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ - ast_reentrancy_lock(lt); - if (lt->reentrancy && (lt->thread[ROFFSET] != pthread_self())) { - __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n", - filename, lineno, func, mutex_name); - __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n", - lt->file[ROFFSET], lt->lineno[ROFFSET], lt->func[ROFFSET], mutex_name); + if (t->tracking && !t->track) { + ast_reentrancy_init(&t->track); + } + lt = t->track; + + if (t->tracking) { + ast_reentrancy_lock(lt); + if (lt->reentrancy && (lt->thread[ROFFSET] != pthread_self())) { + __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n", + filename, lineno, func, mutex_name); + __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n", + lt->file[ROFFSET], lt->lineno[ROFFSET], lt->func[ROFFSET], mutex_name); #ifdef HAVE_BKTR - __dump_backtrace(<->backtrace[ROFFSET], canlog); + __dump_backtrace(<->backtrace[ROFFSET], canlog); #endif - DO_THREAD_CRASH; - } + DO_THREAD_CRASH; + } - if (--lt->reentrancy < 0) { - __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n", - filename, lineno, func, mutex_name); - lt->reentrancy = 0; - } + if (--lt->reentrancy < 0) { + __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n", + filename, lineno, func, mutex_name); + lt->reentrancy = 0; + } - if (lt->reentrancy < AST_MAX_REENTRANCY) { - lt->file[lt->reentrancy] = NULL; - lt->lineno[lt->reentrancy] = 0; - lt->func[lt->reentrancy] = NULL; - lt->thread[lt->reentrancy] = 0; - } + if (lt->reentrancy < AST_MAX_REENTRANCY) { + lt->file[lt->reentrancy] = NULL; + lt->lineno[lt->reentrancy] = 0; + lt->func[lt->reentrancy] = NULL; + lt->thread[lt->reentrancy] = 0; + } #ifdef HAVE_BKTR - if (lt->reentrancy) { - bt = <->backtrace[lt->reentrancy - 1]; - } + if (lt->reentrancy) { + bt = <->backtrace[lt->reentrancy - 1]; + } #endif - ast_reentrancy_unlock(lt); + ast_reentrancy_unlock(lt); - if (t->tracking) { #ifdef HAVE_BKTR ast_remove_lock_info(t, bt); #else @@ -624,7 +651,7 @@ __ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n", filename, lineno, func, strerror(res)); DO_THREAD_CRASH; - } else { + } else if (t->tracking) { ast_reentrancy_lock(lt); if (lt->reentrancy < AST_MAX_REENTRANCY) { lt->file[lt->reentrancy] = filename; @@ -642,13 +669,11 @@ } ast_reentrancy_unlock(lt); - if (t->tracking) { #ifdef HAVE_BKTR - ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, t, bt); + ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, t, bt); #else - ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, t); + ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, t); #endif - } } #endif /* DEBUG_THREADS */ @@ -661,10 +686,9 @@ pthread_rwlockattr_t attr; #ifdef DEBUG_THREADS - struct ast_lock_track *lt= &t->track; #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) && defined(CAN_COMPARE_MUTEX_TO_INIT_VALUE) - int canlog = strcmp(filename, "logger.c") & t->tracking; + int canlog = strcmp(filename, "logger.c") & t->tracking; if (t->lock != ((pthread_rwlock_t) __AST_RWLOCK_INIT_VALUE)) { __ast_mutex_logger("%s line %d (%s): Warning: rwlock '%s' is already initialized.\n", @@ -673,8 +697,9 @@ } #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ - ast_reentrancy_init(lt); - t->tracking = tracking; + if ((t->tracking = tracking)) { + ast_reentrancy_init(&t->track); + } #endif /* DEBUG_THREADS */ pthread_rwlockattr_init(&attr); @@ -693,7 +718,7 @@ int res; #ifdef DEBUG_THREADS - struct ast_lock_track *lt = &t->track; + struct ast_lock_track *lt = t->track; int canlog = strcmp(filename, "logger.c") & t->tracking; #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) && defined(CAN_COMPARE_MUTEX_TO_INIT_VALUE) @@ -713,29 +738,30 @@ __ast_mutex_logger("%s line %d (%s): Error destroying rwlock %s: %s\n", filename, lineno, func, rwlock_name, strerror(res)); } - ast_reentrancy_lock(lt); - lt->file[0] = filename; - lt->lineno[0] = lineno; - lt->func[0] = func; - lt->reentrancy = 0; - lt->thread[0] = 0; + if (t->tracking) { + ast_reentrancy_lock(lt); + lt->file[0] = filename; + lt->lineno[0] = lineno; + lt->func[0] = func; + lt->reentrancy = 0; + lt->thread[0] = 0; #ifdef HAVE_BKTR - memset(<->backtrace[0], 0, sizeof(lt->backtrace[0])); + memset(<->backtrace[0], 0, sizeof(lt->backtrace[0])); #endif - ast_reentrancy_unlock(lt); - delete_reentrancy_cs(lt); + ast_reentrancy_unlock(lt); + delete_reentrancy_cs(&t->track); + } #endif /* DEBUG_THREADS */ return res; } -int __ast_rwlock_unlock(ast_rwlock_t *t, const char *name, - const char *filename, int line, const char *func) +int __ast_rwlock_unlock(const char *filename, int line, const char *func, ast_rwlock_t *t, const char *name) { int res; #ifdef DEBUG_THREADS - struct ast_lock_track *lt = &t->track; + struct ast_lock_track *lt; int canlog = strcmp(filename, "logger.c") & t->tracking; #ifdef HAVE_BKTR struct ast_bt *bt = NULL; @@ -756,40 +782,45 @@ } #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ - ast_reentrancy_lock(lt); - if (lt->reentrancy) { - int i; - pthread_t self = pthread_self(); - for (i = lt->reentrancy - 1; i >= 0; --i) { - if (lt->thread[i] == self) { - lock_found = 1; - if (i != lt->reentrancy - 1) { - lt->file[i] = lt->file[lt->reentrancy - 1]; - lt->lineno[i] = lt->lineno[lt->reentrancy - 1]; - lt->func[i] = lt->func[lt->reentrancy - 1]; - lt->thread[i] = lt->thread[lt->reentrancy - 1]; - } + if (t->tracking && !t->track) { + ast_reentrancy_init(&t->track); + } + lt = t->track; + + if (t->tracking) { + ast_reentrancy_lock(lt); + if (lt->reentrancy) { + int i; + pthread_t self = pthread_self(); + for (i = lt->reentrancy - 1; i >= 0; --i) { + if (lt->thread[i] == self) { + lock_found = 1; + if (i != lt->reentrancy - 1) { + lt->file[i] = lt->file[lt->reentrancy - 1]; + lt->lineno[i] = lt->lineno[lt->reentrancy - 1]; + lt->func[i] = lt->func[lt->reentrancy - 1]; + lt->thread[i] = lt->thread[lt->reentrancy - 1]; + } #ifdef HAVE_BKTR - bt = <->backtrace[i]; + bt = <->backtrace[i]; #endif - lt->file[lt->reentrancy - 1] = NULL; - lt->lineno[lt->reentrancy - 1] = 0; - lt->func[lt->reentrancy - 1] = NULL; - lt->thread[lt->reentrancy - 1] = AST_PTHREADT_NULL; - break; + lt->file[lt->reentrancy - 1] = NULL; + lt->lineno[lt->reentrancy - 1] = 0; + lt->func[lt->reentrancy - 1] = NULL; + lt->thread[lt->reentrancy - 1] = AST_PTHREADT_NULL; + break; + } } } - } - if (lock_found && --lt->reentrancy < 0) { - __ast_mutex_logger("%s line %d (%s): rwlock '%s' freed more times than we've locked!\n", - filename, line, func, name); - lt->reentrancy = 0; - } + if (lock_found && --lt->reentrancy < 0) { + __ast_mutex_logger("%s line %d (%s): rwlock '%s' freed more times than we've locked!\n", + filename, line, func, name); + lt->reentrancy = 0; + } - ast_reentrancy_unlock(lt); + ast_reentrancy_unlock(lt); - if (t->tracking) { #ifdef HAVE_BKTR ast_remove_lock_info(t, bt); #else @@ -811,13 +842,12 @@ return res; } -int __ast_rwlock_rdlock(ast_rwlock_t *t, const char *name, - const char *filename, int line, const char *func) +int __ast_rwlock_rdlock(const char *filename, int line, const char *func, ast_rwlock_t *t, const char *name) { int res; #ifdef DEBUG_THREADS - struct ast_lock_track *lt = &t->track; + struct ast_lock_track *lt; int canlog = strcmp(filename, "logger.c") & t->tracking; #ifdef HAVE_BKTR struct ast_bt *bt = NULL; @@ -838,6 +868,11 @@ } #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ + if (t->tracking && !t->track) { + ast_reentrancy_init(&t->track); + } + lt = t->track; + if (t->tracking) { #ifdef HAVE_BKTR ast_reentrancy_lock(lt); @@ -864,17 +899,19 @@ if (wait_time > reported_wait && (wait_time % 5) == 0) { __ast_mutex_logger("%s line %d (%s): Deadlock? waited %d sec for readlock '%s'?\n", filename, line, func, (int)wait_time, name); - ast_reentrancy_lock(lt); + if (t->tracking) { + ast_reentrancy_lock(lt); #ifdef HAVE_BKTR - __dump_backtrace(<->backtrace[lt->reentrancy], canlog); + __dump_backtrace(<->backtrace[lt->reentrancy], canlog); #endif - __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n", - lt->file[lt->reentrancy-1], lt->lineno[lt->reentrancy-1], - lt->func[lt->reentrancy-1], name); + __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n", + lt->file[lt->reentrancy-1], lt->lineno[lt->reentrancy-1], + lt->func[lt->reentrancy-1], name); #ifdef HAVE_BKTR - __dump_backtrace(<->backtrace[lt->reentrancy-1], canlog); + __dump_backtrace(<->backtrace[lt->reentrancy-1], canlog); #endif - ast_reentrancy_unlock(lt); + ast_reentrancy_unlock(lt); + } reported_wait = wait_time; } usleep(200); @@ -886,7 +923,7 @@ #endif /* !DETECT_DEADLOCKS || !DEBUG_THREADS */ #ifdef DEBUG_THREADS - if (!res) { + if (!res && t->tracking) { ast_reentrancy_lock(lt); if (lt->reentrancy < AST_MAX_REENTRANCY) { lt->file[lt->reentrancy] = filename; @@ -899,7 +936,7 @@ if (t->tracking) { ast_mark_lock_acquired(t); } - } else { + } else if (t->tracking) { #ifdef HAVE_BKTR if (lt->reentrancy) { ast_reentrancy_lock(lt); @@ -908,14 +945,13 @@ } else { bt = NULL; } - if (t->tracking) { - ast_remove_lock_info(t, bt); - } + ast_remove_lock_info(t, bt); #else - if (t->tracking) { - ast_remove_lock_info(t); - } + ast_remove_lock_info(t); #endif + } + + if (res) { __ast_mutex_logger("%s line %d (%s): Error obtaining read lock: %s\n", filename, line, func, strerror(res)); DO_THREAD_CRASH; @@ -925,13 +961,12 @@ return res; } -int __ast_rwlock_wrlock(ast_rwlock_t *t, const char *name, - const char *filename, int line, const char *func) +int __ast_rwlock_wrlock(const char *filename, int line, const char *func, ast_rwlock_t *t, const char *name) { int res; #ifdef DEBUG_THREADS - struct ast_lock_track *lt = &t->track; + struct ast_lock_track *lt; int canlog = strcmp(filename, "logger.c") & t->tracking; #ifdef HAVE_BKTR struct ast_bt *bt = NULL; @@ -952,6 +987,11 @@ } #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ + if (t->tracking && !t->track) { + ast_reentrancy_init(&t->track); + } + lt = t->track; + if (t->tracking) { #ifdef HAVE_BKTR ast_reentrancy_lock(lt); @@ -978,17 +1018,19 @@ if (wait_time > reported_wait && (wait_time % 5) == 0) { __ast_mutex_logger("%s line %d (%s): Deadlock? waited %d sec for writelock '%s'?\n", filename, line, func, (int)wait_time, name); - ast_reentrancy_lock(lt); + if (t->tracking) { + ast_reentrancy_lock(lt); #ifdef HAVE_BKTR - __dump_backtrace(<->backtrace[lt->reentrancy], canlog); + __dump_backtrace(<->backtrace[lt->reentrancy], canlog); #endif - __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n", - lt->file[lt->reentrancy-1], lt->lineno[lt->reentrancy-1], - lt->func[lt->reentrancy-1], name); + __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n", + lt->file[lt->reentrancy-1], lt->lineno[lt->reentrancy-1], + lt->func[lt->reentrancy-1], name); #ifdef HAVE_BKTR - __dump_backtrace(<->backtrace[lt->reentrancy-1], canlog); + __dump_backtrace(<->backtrace[lt->reentrancy-1], canlog); #endif - ast_reentrancy_unlock(lt); + ast_reentrancy_unlock(lt); + } reported_wait = wait_time; } usleep(200); @@ -1000,7 +1042,7 @@ #endif /* !DETECT_DEADLOCKS || !DEBUG_THREADS */ #ifdef DEBUG_THREADS - if (!res) { + if (!res && t->tracking) { ast_reentrancy_lock(lt); if (lt->reentrancy < AST_MAX_REENTRANCY) { lt->file[lt->reentrancy] = filename; @@ -1013,7 +1055,7 @@ if (t->tracking) { ast_mark_lock_acquired(t); } - } else { + } else if (t->tracking) { #ifdef HAVE_BKTR if (lt->reentrancy) { ast_reentrancy_lock(lt); @@ -1030,6 +1072,8 @@ ast_remove_lock_info(t); } #endif + } + if (res) { __ast_mutex_logger("%s line %d (%s): Error obtaining write lock: %s\n", filename, line, func, strerror(res)); DO_THREAD_CRASH; @@ -1039,13 +1083,13 @@ return res; } -int __ast_rwlock_timedrdlock(ast_rwlock_t *t, const char *name, - const struct timespec *abs_timeout, const char *filename, int line, const char *func) +int __ast_rwlock_timedrdlock(const char *filename, int line, const char *func, ast_rwlock_t *t, const char *name, + const struct timespec *abs_timeout) { int res; #ifdef DEBUG_THREADS - struct ast_lock_track *lt = &t->track; + struct ast_lock_track *lt; int canlog = strcmp(filename, "logger.c") & t->tracking; #ifdef HAVE_BKTR struct ast_bt *bt = NULL; @@ -1066,6 +1110,11 @@ } #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ + if (t->tracking && !t->track) { + ast_reentrancy_init(&t->track); + } + lt = t->track; + if (t->tracking) { #ifdef HAVE_BKTR ast_reentrancy_lock(lt); @@ -1100,7 +1149,7 @@ #endif #ifdef DEBUG_THREADS - if (!res) { + if (!res && t->tracking) { ast_reentrancy_lock(lt); if (lt->reentrancy < AST_MAX_REENTRANCY) { lt->file[lt->reentrancy] = filename; @@ -1113,7 +1162,7 @@ if (t->tracking) { ast_mark_lock_acquired(t); } - } else { + } else if (t->tracking) { #ifdef HAVE_BKTR if (lt->reentrancy) { ast_reentrancy_lock(lt); @@ -1122,14 +1171,12 @@ } else { bt = NULL; } - if (t->tracking) { - ast_remove_lock_info(t, bt); - } + ast_remove_lock_info(t, bt); #else - if (t->tracking) { - ast_remove_lock_info(t); - } + ast_remove_lock_info(t); #endif + } + if (res) { __ast_mutex_logger("%s line %d (%s): Error obtaining read lock: %s\n", filename, line, func, strerror(res)); DO_THREAD_CRASH; @@ -1139,13 +1186,13 @@ return res; } -int __ast_rwlock_timedwrlock(ast_rwlock_t *t, const char *name, - const struct timespec *abs_timeout, const char *filename, int line, const char *func) +int __ast_rwlock_timedwrlock(const char *filename, int line, const char *func, ast_rwlock_t *t, const char *name, + const struct timespec *abs_timeout) { int res; #ifdef DEBUG_THREADS - struct ast_lock_track *lt = &t->track; + struct ast_lock_track *lt; int canlog = strcmp(filename, "logger.c") & t->tracking; #ifdef HAVE_BKTR struct ast_bt *bt = NULL; @@ -1166,6 +1213,11 @@ } #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ + if (t->tracking && !t->track) { + ast_reentrancy_init(&t->track); + } + lt = t->track; + if (t->tracking) { #ifdef HAVE_BKTR ast_reentrancy_lock(lt); @@ -1200,7 +1252,7 @@ #endif #ifdef DEBUG_THREADS - if (!res) { + if (!res && t->tracking) { ast_reentrancy_lock(lt); if (lt->reentrancy < AST_MAX_REENTRANCY) { lt->file[lt->reentrancy] = filename; @@ -1213,7 +1265,7 @@ if (t->tracking) { ast_mark_lock_acquired(t); } - } else { + } else if (t->tracking) { #ifdef HAVE_BKTR if (lt->reentrancy) { ast_reentrancy_lock(lt); @@ -1230,6 +1282,8 @@ ast_remove_lock_info(t); } #endif + } + if (res) { __ast_mutex_logger("%s line %d (%s): Error obtaining read lock: %s\n", filename, line, func, strerror(res)); DO_THREAD_CRASH; @@ -1239,13 +1293,12 @@ return res; } -int __ast_rwlock_tryrdlock(ast_rwlock_t *t, const char *name, - const char *filename, int line, const char *func) +int __ast_rwlock_tryrdlock(const char *filename, int line, const char *func, ast_rwlock_t *t, const char *name) { int res; #ifdef DEBUG_THREADS - struct ast_lock_track *lt = &t->track; + struct ast_lock_track *lt; #ifdef HAVE_BKTR struct ast_bt *bt = NULL; #endif @@ -1266,6 +1319,11 @@ } #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ + if (t->tracking && !t->track) { + ast_reentrancy_init(&t->track); + } + lt = t->track; + if (t->tracking) { #ifdef HAVE_BKTR ast_reentrancy_lock(lt); @@ -1284,7 +1342,7 @@ res = pthread_rwlock_tryrdlock(&t->lock); #ifdef DEBUG_THREADS - if (!res) { + if (!res && t->tracking) { ast_reentrancy_lock(lt); if (lt->reentrancy < AST_MAX_REENTRANCY) { lt->file[lt->reentrancy] = filename; @@ -1305,13 +1363,12 @@ return res; } -int __ast_rwlock_trywrlock(ast_rwlock_t *t, const char *name, - const char *filename, int line, const char *func) +int __ast_rwlock_trywrlock(const char *filename, int line, const char *func, ast_rwlock_t *t, const char *name) { int res; #ifdef DEBUG_THREADS - struct ast_lock_track *lt= &t->track; + struct ast_lock_track *lt; #ifdef HAVE_BKTR struct ast_bt *bt = NULL; #endif @@ -1332,6 +1389,11 @@ } #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ + if (t->tracking && !t->track) { + ast_reentrancy_init(&t->track); + } + lt = t->track; + if (t->tracking) { #ifdef HAVE_BKTR ast_reentrancy_lock(lt); @@ -1350,7 +1412,7 @@ res = pthread_rwlock_trywrlock(&t->lock); #ifdef DEBUG_THREADS - if (!res) { + if (!res && t->tracking) { ast_reentrancy_lock(lt); if (lt->reentrancy < AST_MAX_REENTRANCY) { lt->file[lt->reentrancy] = filename; @@ -1360,9 +1422,7 @@ lt->reentrancy++; } ast_reentrancy_unlock(lt); - if (t->tracking) { - ast_mark_lock_acquired(t); - } + ast_mark_lock_acquired(t); } else if (t->tracking) { ast_mark_lock_failed(t); } Property changes on: . ___________________________________________________________________ Added: automerge + * Added: svnmerge-integrated + /branches/1.8:1-303455 Added: automerge-email + tlesher@digium.com