|
|
|
@ -65,21 +65,16 @@ static void __dump_backtrace(struct ast_bt *bt, int canlog)
|
|
|
|
|
#ifdef DEBUG_THREADS
|
|
|
|
|
AST_MUTEX_DEFINE_STATIC(reentrancy_lock);
|
|
|
|
|
|
|
|
|
|
static inline struct ast_lock_track *ast_get_reentrancy(struct ast_lock_track **plt)
|
|
|
|
|
static inline struct ast_lock_track *ast_get_reentrancy(struct ast_lock_track **plt,
|
|
|
|
|
struct ast_lock_track_flags *flags, int no_setup)
|
|
|
|
|
{
|
|
|
|
|
pthread_mutexattr_t reentr_attr;
|
|
|
|
|
struct ast_lock_track *lt;
|
|
|
|
|
|
|
|
|
|
/* It's a bit painful to lock a global mutex for every access to the
|
|
|
|
|
* reentrancy structure, but it's necessary to ensure that we don't
|
|
|
|
|
* double-allocate the structure or double-initialize the reentr_mutex.
|
|
|
|
|
*
|
|
|
|
|
* If you'd like to replace this with a double-checked lock, be sure to
|
|
|
|
|
* properly volatile-ize everything to avoid optimizer bugs.
|
|
|
|
|
*
|
|
|
|
|
* We also have to use the underlying pthread calls for manipulating
|
|
|
|
|
* the mutex, because this is called from the Asterisk mutex code.
|
|
|
|
|
*/
|
|
|
|
|
if (!flags->tracking || flags->setup) {
|
|
|
|
|
return *plt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock(&reentrancy_lock.mutex);
|
|
|
|
|
|
|
|
|
|
if (*plt) {
|
|
|
|
@ -87,6 +82,11 @@ static inline struct ast_lock_track *ast_get_reentrancy(struct ast_lock_track **
|
|
|
|
|
return *plt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (no_setup) {
|
|
|
|
|
pthread_mutex_unlock(&reentrancy_lock.mutex);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lt = *plt = ast_std_calloc(1, sizeof(*lt));
|
|
|
|
|
if (!lt) {
|
|
|
|
|
fprintf(stderr, "%s: Failed to allocate lock tracking\n", __func__);
|
|
|
|
@ -103,6 +103,7 @@ static inline struct ast_lock_track *ast_get_reentrancy(struct ast_lock_track **
|
|
|
|
|
pthread_mutex_init(<->reentr_mutex, &reentr_attr);
|
|
|
|
|
pthread_mutexattr_destroy(&reentr_attr);
|
|
|
|
|
|
|
|
|
|
flags->setup = 1;
|
|
|
|
|
pthread_mutex_unlock(&reentrancy_lock.mutex);
|
|
|
|
|
return lt;
|
|
|
|
|
}
|
|
|
|
@ -141,7 +142,8 @@ int __ast_pthread_mutex_init(int tracking, const char *filename, int lineno, con
|
|
|
|
|
#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
|
|
|
|
|
|
|
|
|
|
t->track = NULL;
|
|
|
|
|
t->tracking = tracking;
|
|
|
|
|
t->flags.tracking = tracking;
|
|
|
|
|
t->flags.setup = 0;
|
|
|
|
|
#endif /* DEBUG_THREADS */
|
|
|
|
|
|
|
|
|
|
pthread_mutexattr_init(&attr);
|
|
|
|
@ -158,8 +160,8 @@ int __ast_pthread_mutex_destroy(const char *filename, int lineno, const char *fu
|
|
|
|
|
int res;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_THREADS
|
|
|
|
|
struct ast_lock_track *lt = t->track;
|
|
|
|
|
int canlog = t->tracking && strcmp(filename, "logger.c");
|
|
|
|
|
struct ast_lock_track *lt = ast_get_reentrancy(&t->track, &t->flags, 1);
|
|
|
|
|
int canlog = t->flags.tracking && strcmp(filename, "logger.c");
|
|
|
|
|
|
|
|
|
|
#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) && defined(CAN_COMPARE_MUTEX_TO_INIT_VALUE)
|
|
|
|
|
if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
|
|
|
|
@ -236,16 +238,12 @@ int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func,
|
|
|
|
|
int res;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_THREADS
|
|
|
|
|
struct ast_lock_track *lt = NULL;
|
|
|
|
|
int canlog = t->tracking && strcmp(filename, "logger.c");
|
|
|
|
|
struct ast_lock_track *lt = ast_get_reentrancy(&t->track, &t->flags, 0);
|
|
|
|
|
int canlog = t->flags.tracking && strcmp(filename, "logger.c");
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt *bt = NULL;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (t->tracking) {
|
|
|
|
|
lt = ast_get_reentrancy(&t->track);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lt) {
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt tmp;
|
|
|
|
@ -360,16 +358,12 @@ int __ast_pthread_mutex_trylock(const char *filename, int lineno, const char *fu
|
|
|
|
|
int res;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_THREADS
|
|
|
|
|
struct ast_lock_track *lt = NULL;
|
|
|
|
|
int canlog = t->tracking && strcmp(filename, "logger.c");
|
|
|
|
|
struct ast_lock_track *lt = ast_get_reentrancy(&t->track, &t->flags, 0);
|
|
|
|
|
int canlog = t->flags.tracking && strcmp(filename, "logger.c");
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt *bt = NULL;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (t->tracking) {
|
|
|
|
|
lt = ast_get_reentrancy(&t->track);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lt) {
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt tmp;
|
|
|
|
@ -425,7 +419,7 @@ int __ast_pthread_mutex_unlock(const char *filename, int lineno, const char *fun
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_THREADS
|
|
|
|
|
struct ast_lock_track *lt = NULL;
|
|
|
|
|
int canlog = t->tracking && strcmp(filename, "logger.c");
|
|
|
|
|
int canlog = t->flags.tracking && strcmp(filename, "logger.c");
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt *bt = NULL;
|
|
|
|
|
#endif
|
|
|
|
@ -439,10 +433,7 @@ int __ast_pthread_mutex_unlock(const char *filename, int lineno, const char *fun
|
|
|
|
|
}
|
|
|
|
|
#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
|
|
|
|
|
|
|
|
|
|
if (t->tracking) {
|
|
|
|
|
lt = ast_get_reentrancy(&t->track);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lt = ast_get_reentrancy(&t->track, &t->flags, 0);
|
|
|
|
|
if (lt) {
|
|
|
|
|
ast_reentrancy_lock(lt);
|
|
|
|
|
if (lt->reentrancy && (lt->thread_id[ROFFSET] != pthread_self())) {
|
|
|
|
@ -554,7 +545,7 @@ int __ast_cond_wait(const char *filename, int lineno, const char *func,
|
|
|
|
|
#ifdef DEBUG_THREADS
|
|
|
|
|
struct ast_lock_track *lt = NULL;
|
|
|
|
|
struct ast_lock_track lt_orig;
|
|
|
|
|
int canlog = t->tracking && strcmp(filename, "logger.c");
|
|
|
|
|
int canlog = t->flags.tracking && strcmp(filename, "logger.c");
|
|
|
|
|
|
|
|
|
|
#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) && defined(CAN_COMPARE_MUTEX_TO_INIT_VALUE)
|
|
|
|
|
if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
|
|
|
|
@ -565,10 +556,7 @@ int __ast_cond_wait(const char *filename, int lineno, const char *func,
|
|
|
|
|
}
|
|
|
|
|
#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
|
|
|
|
|
|
|
|
|
|
if (t->tracking) {
|
|
|
|
|
lt = ast_get_reentrancy(&t->track);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lt = ast_get_reentrancy(&t->track, &t->flags, 0);
|
|
|
|
|
if (lt) {
|
|
|
|
|
ast_reentrancy_lock(lt);
|
|
|
|
|
if (lt->reentrancy && (lt->thread_id[ROFFSET] != pthread_self())) {
|
|
|
|
@ -622,7 +610,7 @@ int __ast_cond_timedwait(const char *filename, int lineno, const char *func,
|
|
|
|
|
#ifdef DEBUG_THREADS
|
|
|
|
|
struct ast_lock_track *lt = NULL;
|
|
|
|
|
struct ast_lock_track lt_orig;
|
|
|
|
|
int canlog = t->tracking && strcmp(filename, "logger.c");
|
|
|
|
|
int canlog = t->flags.tracking && strcmp(filename, "logger.c");
|
|
|
|
|
|
|
|
|
|
#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) && defined(CAN_COMPARE_MUTEX_TO_INIT_VALUE)
|
|
|
|
|
if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
|
|
|
|
@ -633,10 +621,7 @@ int __ast_cond_timedwait(const char *filename, int lineno, const char *func,
|
|
|
|
|
}
|
|
|
|
|
#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
|
|
|
|
|
|
|
|
|
|
if (t->tracking) {
|
|
|
|
|
lt = ast_get_reentrancy(&t->track);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lt = ast_get_reentrancy(&t->track, &t->flags, 0);
|
|
|
|
|
if (lt) {
|
|
|
|
|
ast_reentrancy_lock(lt);
|
|
|
|
|
if (lt->reentrancy && (lt->thread_id[ROFFSET] != pthread_self())) {
|
|
|
|
@ -699,7 +684,8 @@ int __ast_rwlock_init(int tracking, const char *filename, int lineno, const char
|
|
|
|
|
#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
|
|
|
|
|
|
|
|
|
|
t->track = NULL;
|
|
|
|
|
t->tracking = tracking;
|
|
|
|
|
t->flags.tracking = tracking;
|
|
|
|
|
t->flags.setup = 0;
|
|
|
|
|
#endif /* DEBUG_THREADS */
|
|
|
|
|
|
|
|
|
|
pthread_rwlockattr_init(&attr);
|
|
|
|
@ -717,8 +703,8 @@ int __ast_rwlock_destroy(const char *filename, int lineno, const char *func, con
|
|
|
|
|
int res;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_THREADS
|
|
|
|
|
struct ast_lock_track *lt = t->track;
|
|
|
|
|
int canlog = t->tracking && strcmp(filename, "logger.c");
|
|
|
|
|
struct ast_lock_track *lt = ast_get_reentrancy(&t->track, &t->flags, 1);
|
|
|
|
|
int canlog = t->flags.tracking && strcmp(filename, "logger.c");
|
|
|
|
|
|
|
|
|
|
#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) && defined(CAN_COMPARE_MUTEX_TO_INIT_VALUE)
|
|
|
|
|
if (t->lock == ((pthread_rwlock_t) __AST_RWLOCK_INIT_VALUE)) {
|
|
|
|
@ -765,7 +751,7 @@ int __ast_rwlock_unlock(const char *filename, int line, const char *func, ast_rw
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_THREADS
|
|
|
|
|
struct ast_lock_track *lt = NULL;
|
|
|
|
|
int canlog = t->tracking && strcmp(filename, "logger.c");
|
|
|
|
|
int canlog = t->flags.tracking && strcmp(filename, "logger.c");
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt *bt = NULL;
|
|
|
|
|
#endif
|
|
|
|
@ -780,10 +766,7 @@ int __ast_rwlock_unlock(const char *filename, int line, const char *func, ast_rw
|
|
|
|
|
}
|
|
|
|
|
#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
|
|
|
|
|
|
|
|
|
|
if (t->tracking) {
|
|
|
|
|
lt = ast_get_reentrancy(&t->track);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lt = ast_get_reentrancy(&t->track, &t->flags, 0);
|
|
|
|
|
if (lt) {
|
|
|
|
|
ast_reentrancy_lock(lt);
|
|
|
|
|
if (lt->reentrancy) {
|
|
|
|
@ -844,16 +827,12 @@ int __ast_rwlock_rdlock(const char *filename, int line, const char *func, ast_rw
|
|
|
|
|
int res;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_THREADS
|
|
|
|
|
struct ast_lock_track *lt = NULL;
|
|
|
|
|
int canlog = t->tracking && strcmp(filename, "logger.c");
|
|
|
|
|
struct ast_lock_track *lt = ast_get_reentrancy(&t->track, &t->flags, 0);
|
|
|
|
|
int canlog = t->flags.tracking && strcmp(filename, "logger.c");
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt *bt = NULL;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (t->tracking) {
|
|
|
|
|
lt = ast_get_reentrancy(&t->track);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lt) {
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt tmp;
|
|
|
|
@ -953,16 +932,12 @@ int __ast_rwlock_wrlock(const char *filename, int line, const char *func, ast_rw
|
|
|
|
|
int res;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_THREADS
|
|
|
|
|
struct ast_lock_track *lt = NULL;
|
|
|
|
|
int canlog = t->tracking && strcmp(filename, "logger.c");
|
|
|
|
|
struct ast_lock_track *lt = ast_get_reentrancy(&t->track, &t->flags, 0);
|
|
|
|
|
int canlog = t->flags.tracking && strcmp(filename, "logger.c");
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt *bt = NULL;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (t->tracking) {
|
|
|
|
|
lt = ast_get_reentrancy(&t->track);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lt) {
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt tmp;
|
|
|
|
@ -1062,16 +1037,12 @@ int __ast_rwlock_timedrdlock(const char *filename, int line, const char *func, a
|
|
|
|
|
int res;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_THREADS
|
|
|
|
|
struct ast_lock_track *lt = NULL;
|
|
|
|
|
int canlog = t->tracking && strcmp(filename, "logger.c");
|
|
|
|
|
struct ast_lock_track *lt = ast_get_reentrancy(&t->track, &t->flags, 0);
|
|
|
|
|
int canlog = t->flags.tracking && strcmp(filename, "logger.c");
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt *bt = NULL;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (t->tracking) {
|
|
|
|
|
lt = ast_get_reentrancy(&t->track);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lt) {
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt tmp;
|
|
|
|
@ -1155,16 +1126,12 @@ int __ast_rwlock_timedwrlock(const char *filename, int line, const char *func, a
|
|
|
|
|
int res;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_THREADS
|
|
|
|
|
struct ast_lock_track *lt = NULL;
|
|
|
|
|
int canlog = t->tracking && strcmp(filename, "logger.c");
|
|
|
|
|
struct ast_lock_track *lt = ast_get_reentrancy(&t->track, &t->flags, 0);
|
|
|
|
|
int canlog = t->flags.tracking && strcmp(filename, "logger.c");
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt *bt = NULL;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (t->tracking) {
|
|
|
|
|
lt = ast_get_reentrancy(&t->track);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lt) {
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt tmp;
|
|
|
|
@ -1247,15 +1214,11 @@ int __ast_rwlock_tryrdlock(const char *filename, int line, const char *func, ast
|
|
|
|
|
int res;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_THREADS
|
|
|
|
|
struct ast_lock_track *lt = NULL;
|
|
|
|
|
struct ast_lock_track *lt = ast_get_reentrancy(&t->track, &t->flags, 0);
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt *bt = NULL;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (t->tracking) {
|
|
|
|
|
lt = ast_get_reentrancy(&t->track);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lt) {
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt tmp;
|
|
|
|
@ -1306,15 +1269,11 @@ int __ast_rwlock_trywrlock(const char *filename, int line, const char *func, ast
|
|
|
|
|
int res;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_THREADS
|
|
|
|
|
struct ast_lock_track *lt = NULL;
|
|
|
|
|
struct ast_lock_track *lt = ast_get_reentrancy(&t->track, &t->flags, 0);
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt *bt = NULL;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (t->tracking) {
|
|
|
|
|
lt = ast_get_reentrancy(&t->track);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lt) {
|
|
|
|
|
#ifdef HAVE_BKTR
|
|
|
|
|
struct ast_bt tmp;
|
|
|
|
|