@ -208,12 +208,20 @@ int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func,
if ( t - > tracking ) {
# ifdef HAVE_BKTR
struct ast_bt tmp ;
/* The implementation of backtrace() may have its own locks.
* Capture the backtrace outside of the reentrancy lock to
* avoid deadlocks . See ASTERISK - 22455. */
ast_bt_get_addresses ( & tmp ) ;
ast_reentrancy_lock ( lt ) ;
if ( lt - > reentrancy ! = AST_MAX_REENTRANCY ) {
ast_bt_get_addresses ( & lt - > backtrace [ lt - > reentrancy ] ) ;
lt - > backtrace [ lt - > reentrancy ] = tmp ;
bt = & lt - > backtrace [ lt - > reentrancy ] ;
}
ast_reentrancy_unlock ( lt ) ;
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 ) ;
@ -340,12 +348,20 @@ int __ast_pthread_mutex_trylock(const char *filename, int lineno, const char *fu
if ( t - > tracking ) {
# ifdef HAVE_BKTR
struct ast_bt tmp ;
/* The implementation of backtrace() may have its own locks.
* Capture the backtrace outside of the reentrancy lock to
* avoid deadlocks . See ASTERISK - 22455. */
ast_bt_get_addresses ( & tmp ) ;
ast_reentrancy_lock ( lt ) ;
if ( lt - > reentrancy ! = AST_MAX_REENTRANCY ) {
ast_bt_get_addresses ( & lt - > backtrace [ lt - > reentrancy ] ) ;
lt - > backtrace [ lt - > reentrancy ] = tmp ;
bt = & lt - > backtrace [ lt - > reentrancy ] ;
}
ast_reentrancy_unlock ( lt ) ;
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 ) ;
@ -497,10 +513,8 @@ int __ast_cond_wait(const char *filename, int lineno, const char *func,
# ifdef DEBUG_THREADS
struct ast_lock_track * lt ;
struct ast_lock_track lt_orig ;
int canlog = strcmp ( filename , " logger.c " ) & t - > tracking ;
# ifdef HAVE_BKTR
struct ast_bt * bt = NULL ;
# endif
# if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) && defined(CAN_COMPARE_MUTEX_TO_INIT_VALUE)
if ( ( t - > mutex ) = = ( ( pthread_mutex_t ) PTHREAD_MUTEX_INITIALIZER ) ) {
@ -531,33 +545,20 @@ int __ast_cond_wait(const char *filename, int lineno, const char *func,
__dump_backtrace ( & lt - > backtrace [ ROFFSET ] , canlog ) ;
# endif
DO_THREAD_CRASH ;
} else if ( lt - > reentrancy < = 0 ) {
__ast_mutex_logger ( " %s line %d (%s): attempted to wait on an unlocked mutex '%s' \n " ,
filename , lineno , func , mutex_name ) ;
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 < 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 = & lt - > backtrace [ lt - > reentrancy - 1 ] ;
}
# endif
/* Waiting on a condition completely suspends a recursive mutex,
* even if it ' s been recursively locked multiple times . Make a
* copy of the lock tracking , and reset reentrancy to zero */
lt_orig = * lt ;
lt - > reentrancy = 0 ;
ast_reentrancy_unlock ( lt ) ;
# ifdef HAVE_BKTR
ast_remove_lock_info ( t , bt ) ;
# else
ast_remove_lock_info ( t ) ;
# endif
ast_suspend_lock_info ( t ) ;
}
# endif /* DEBUG_THREADS */
@ -569,28 +570,16 @@ int __ast_cond_wait(const char *filename, int lineno, const char *func,
filename , lineno , func , strerror ( res ) ) ;
DO_THREAD_CRASH ;
} else if ( t - > tracking ) {
pthread_mutex_t reentr_mutex_orig ;
ast_reentrancy_lock ( lt ) ;
if ( lt - > reentrancy < AST_MAX_REENTRANCY ) {
lt - > file [ lt - > reentrancy ] = filename ;
lt - > lineno [ lt - > reentrancy ] = lineno ;
lt - > func [ lt - > reentrancy ] = func ;
lt - > thread [ lt - > reentrancy ] = pthread_self ( ) ;
# ifdef HAVE_BKTR
ast_bt_get_addresses ( & lt - > backtrace [ lt - > reentrancy ] ) ;
bt = & lt - > backtrace [ lt - > reentrancy ] ;
# endif
lt - > reentrancy + + ;
} else {
__ast_mutex_logger ( " %s line %d (%s): '%s' really deep reentrancy! \n " ,
filename , lineno , func , mutex_name ) ;
}
/* Restore lock tracking to what it was prior to the wait */
reentr_mutex_orig = lt - > reentr_mutex ;
* lt = lt_orig ;
/* un-trash the mutex we just copied over */
lt - > reentr_mutex = reentr_mutex_orig ;
ast_reentrancy_unlock ( lt ) ;
# ifdef HAVE_BKTR
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 ) ;
# endif
ast_restore_lock_info ( t ) ;
}
# endif /* DEBUG_THREADS */
@ -605,10 +594,8 @@ int __ast_cond_timedwait(const char *filename, int lineno, const char *func,
# ifdef DEBUG_THREADS
struct ast_lock_track * lt ;
struct ast_lock_track lt_orig ;
int canlog = strcmp ( filename , " logger.c " ) & t - > tracking ;
# ifdef HAVE_BKTR
struct ast_bt * bt = NULL ;
# endif
# if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) && defined(CAN_COMPARE_MUTEX_TO_INIT_VALUE)
if ( ( t - > mutex ) = = ( ( pthread_mutex_t ) PTHREAD_MUTEX_INITIALIZER ) ) {
@ -639,32 +626,20 @@ int __ast_cond_timedwait(const char *filename, int lineno, const char *func,
__dump_backtrace ( & lt - > backtrace [ ROFFSET ] , canlog ) ;
# endif
DO_THREAD_CRASH ;
}
if ( - - lt - > reentrancy < 0 ) {
__ast_mutex_logger ( " %s line %d (%s): mutex '%s' freed more times than we've locked! \n " ,
} else if ( lt - > reentrancy < = 0 ) {
__ast_mutex_logger ( " %s line %d (%s): attempted to wait on an unlocked mutex '%s' \n " ,
filename , lineno , func , mutex_name ) ;
lt- > reentrancy = 0 ;
DO_THREAD_CRASH ;
}
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 = & lt - > backtrace [ lt - > reentrancy - 1 ] ;
}
# endif
/* Waiting on a condition completely suspends a recursive mutex,
* even if it ' s been recursively locked multiple times . Make a
* copy of the lock tracking , and reset reentrancy to zero */
lt_orig = * lt ;
lt - > reentrancy = 0 ;
ast_reentrancy_unlock ( lt ) ;
# ifdef HAVE_BKTR
ast_remove_lock_info ( t , bt ) ;
# else
ast_remove_lock_info ( t ) ;
# endif
ast_suspend_lock_info ( t ) ;
}
# endif /* DEBUG_THREADS */
@ -676,28 +651,16 @@ int __ast_cond_timedwait(const char *filename, int lineno, const char *func,
filename , lineno , func , strerror ( res ) ) ;
DO_THREAD_CRASH ;
} else if ( t - > tracking ) {
pthread_mutex_t reentr_mutex_orig ;
ast_reentrancy_lock ( lt ) ;
if ( lt - > reentrancy < AST_MAX_REENTRANCY ) {
lt - > file [ lt - > reentrancy ] = filename ;
lt - > lineno [ lt - > reentrancy ] = lineno ;
lt - > func [ lt - > reentrancy ] = func ;
lt - > thread [ lt - > reentrancy ] = pthread_self ( ) ;
# ifdef HAVE_BKTR
ast_bt_get_addresses ( & lt - > backtrace [ lt - > reentrancy ] ) ;
bt = & lt - > backtrace [ lt - > reentrancy ] ;
# endif
lt - > reentrancy + + ;
} else {
__ast_mutex_logger ( " %s line %d (%s): '%s' really deep reentrancy! \n " ,
filename , lineno , func , mutex_name ) ;
}
/* Restore lock tracking to what it was prior to the wait */
reentr_mutex_orig = lt - > reentr_mutex ;
* lt = lt_orig ;
/* un-trash the mutex we just copied over */
lt - > reentr_mutex = reentr_mutex_orig ;
ast_reentrancy_unlock ( lt ) ;
# ifdef HAVE_BKTR
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 ) ;
# endif
ast_suspend_lock_info ( t ) ;
}
# endif /* DEBUG_THREADS */
@ -899,12 +862,20 @@ int __ast_rwlock_rdlock(const char *filename, int line, const char *func, ast_rw
if ( t - > tracking ) {
# ifdef HAVE_BKTR
struct ast_bt tmp ;
/* The implementation of backtrace() may have its own locks.
* Capture the backtrace outside of the reentrancy lock to
* avoid deadlocks . See ASTERISK - 22455. */
ast_bt_get_addresses ( & tmp ) ;
ast_reentrancy_lock ( lt ) ;
if ( lt - > reentrancy ! = AST_MAX_REENTRANCY ) {
ast_bt_get_addresses ( & lt - > backtrace [ lt - > reentrancy ] ) ;
lt - > backtrace [ lt - > reentrancy ] = tmp ;
bt = & lt - > backtrace [ lt - > reentrancy ] ;
}
ast_reentrancy_unlock ( lt ) ;
ast_store_lock_info ( AST_RDLOCK , filename , line , func , name , t , bt ) ;
# else
ast_store_lock_info ( AST_RDLOCK , filename , line , func , name , t ) ;
@ -1018,12 +989,20 @@ int __ast_rwlock_wrlock(const char *filename, int line, const char *func, ast_rw
if ( t - > tracking ) {
# ifdef HAVE_BKTR
struct ast_bt tmp ;
/* The implementation of backtrace() may have its own locks.
* Capture the backtrace outside of the reentrancy lock to
* avoid deadlocks . See ASTERISK - 22455. */
ast_bt_get_addresses ( & tmp ) ;
ast_reentrancy_lock ( lt ) ;
if ( lt - > reentrancy ! = AST_MAX_REENTRANCY ) {
ast_bt_get_addresses ( & lt - > backtrace [ lt - > reentrancy ] ) ;
lt - > backtrace [ lt - > reentrancy ] = tmp ;
bt = & lt - > backtrace [ lt - > reentrancy ] ;
}
ast_reentrancy_unlock ( lt ) ;
ast_store_lock_info ( AST_WRLOCK , filename , line , func , name , t , bt ) ;
# else
ast_store_lock_info ( AST_WRLOCK , filename , line , func , name , t ) ;
@ -1141,12 +1120,20 @@ int __ast_rwlock_timedrdlock(const char *filename, int line, const char *func, a
if ( t - > tracking ) {
# ifdef HAVE_BKTR
struct ast_bt tmp ;
/* The implementation of backtrace() may have its own locks.
* Capture the backtrace outside of the reentrancy lock to
* avoid deadlocks . See ASTERISK - 22455. */
ast_bt_get_addresses ( & tmp ) ;
ast_reentrancy_lock ( lt ) ;
if ( lt - > reentrancy ! = AST_MAX_REENTRANCY ) {
ast_bt_get_addresses ( & lt - > backtrace [ lt - > reentrancy ] ) ;
lt - > backtrace [ lt - > reentrancy ] = tmp ;
bt = & lt - > backtrace [ lt - > reentrancy ] ;
}
ast_reentrancy_unlock ( lt ) ;
ast_store_lock_info ( AST_WRLOCK , filename , line , func , name , t , bt ) ;
# else
ast_store_lock_info ( AST_WRLOCK , filename , line , func , name , t ) ;
@ -1244,12 +1231,20 @@ int __ast_rwlock_timedwrlock(const char *filename, int line, const char *func, a
if ( t - > tracking ) {
# ifdef HAVE_BKTR
struct ast_bt tmp ;
/* The implementation of backtrace() may have its own locks.
* Capture the backtrace outside of the reentrancy lock to
* avoid deadlocks . See ASTERISK - 22455. */
ast_bt_get_addresses ( & tmp ) ;
ast_reentrancy_lock ( lt ) ;
if ( lt - > reentrancy ! = AST_MAX_REENTRANCY ) {
ast_bt_get_addresses ( & lt - > backtrace [ lt - > reentrancy ] ) ;
lt - > backtrace [ lt - > reentrancy ] = tmp ;
bt = & lt - > backtrace [ lt - > reentrancy ] ;
}
ast_reentrancy_unlock ( lt ) ;
ast_store_lock_info ( AST_WRLOCK , filename , line , func , name , t , bt ) ;
# else
ast_store_lock_info ( AST_WRLOCK , filename , line , func , name , t ) ;
@ -1350,12 +1345,20 @@ int __ast_rwlock_tryrdlock(const char *filename, int line, const char *func, ast
if ( t - > tracking ) {
# ifdef HAVE_BKTR
struct ast_bt tmp ;
/* The implementation of backtrace() may have its own locks.
* Capture the backtrace outside of the reentrancy lock to
* avoid deadlocks . See ASTERISK - 22455. */
ast_bt_get_addresses ( & tmp ) ;
ast_reentrancy_lock ( lt ) ;
if ( lt - > reentrancy ! = AST_MAX_REENTRANCY ) {
ast_bt_get_addresses ( & lt - > backtrace [ lt - > reentrancy ] ) ;
lt - > backtrace [ lt - > reentrancy ] = tmp ;
bt = & lt - > backtrace [ lt - > reentrancy ] ;
}
ast_reentrancy_unlock ( lt ) ;
ast_store_lock_info ( AST_RDLOCK , filename , line , func , name , t , bt ) ;
# else
ast_store_lock_info ( AST_RDLOCK , filename , line , func , name , t ) ;
@ -1420,12 +1423,20 @@ int __ast_rwlock_trywrlock(const char *filename, int line, const char *func, ast
if ( t - > tracking ) {
# ifdef HAVE_BKTR
struct ast_bt tmp ;
/* The implementation of backtrace() may have its own locks.
* Capture the backtrace outside of the reentrancy lock to
* avoid deadlocks . See ASTERISK - 22455. */
ast_bt_get_addresses ( & tmp ) ;
ast_reentrancy_lock ( lt ) ;
if ( lt - > reentrancy ! = AST_MAX_REENTRANCY ) {
ast_bt_get_addresses ( & lt - > backtrace [ lt - > reentrancy ] ) ;
lt - > backtrace [ lt - > reentrancy ] = tmp ;
bt = & lt - > backtrace [ lt - > reentrancy ] ;
}
ast_reentrancy_unlock ( lt ) ;
ast_store_lock_info ( AST_WRLOCK , filename , line , func , name , t , bt ) ;
# else
ast_store_lock_info ( AST_WRLOCK , filename , line , func , name , t ) ;