@ -55,6 +55,7 @@
# include "asterisk/time.h"
# endif
# include "asterisk/logger.h"
# include "asterisk/compiler.h"
/* internal macro to profile mutexes. Only computes the delay on
* non - blocking calls .
@ -204,13 +205,21 @@ int ast_find_lock_info(void *lock_addr, char *filename, size_t filename_size, in
do { \
char __filename [ 80 ] , __func [ 80 ] , __mutex_name [ 80 ] ; \
int __lineno ; \
int __res = ast_find_lock_info ( lock , __filename , sizeof ( __filename ) , & __lineno , __func , sizeof ( __func ) , __mutex_name , sizeof ( __mutex_name ) ) ; \
ast_mutex_unlock ( lock ) ; \
int __res 2, __res = ast_find_lock_info ( lock , __filename , sizeof ( __filename ) , & __lineno , __func , sizeof ( __func ) , __mutex_name , sizeof ( __mutex_name ) ) ; \
__res2 = ast_mutex_unlock ( lock ) ; \
usleep ( 1 ) ; \
if ( __res < 0 ) { /* Shouldn't ever happen, but just in case... */ \
ast_mutex_lock ( lock ) ; \
if ( __res2 = = 0 ) { \
ast_mutex_lock ( lock ) ; \
} else { \
ast_log ( LOG_WARNING , " Could not unlock mutex '%s': %s and no lock info found! I will NOT try to relock. \n " , # lock , strerror ( __res2 ) ) ; \
} \
} else { \
__ast_pthread_mutex_lock ( __filename , __lineno , __func , __mutex_name , lock ) ; \
if ( __res2 = = 0 ) { \
__ast_pthread_mutex_lock ( __filename , __lineno , __func , __mutex_name , lock ) ; \
} else { \
ast_log ( LOG_WARNING , " Could not unlock mutex '%s': %s. {{{Originally locked at %s line %d: (%s) '%s'}}} I will NOT try to relock. \n " , # lock , strerror ( __res2 ) , __filename , __lineno , __func , __mutex_name ) ; \
} \
} \
} while ( 0 )
@ -432,6 +441,8 @@ static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, con
return res ;
}
static inline int __ast_pthread_mutex_trylock ( const char * filename , int lineno , const char * func ,
const char * mutex_name , ast_mutex_t * t ) attribute_warn_unused_result ;
static inline int __ast_pthread_mutex_trylock ( const char * filename , int lineno , const char * func ,
const char * mutex_name , ast_mutex_t * t )
{
@ -712,9 +723,15 @@ static inline int __ast_cond_timedwait(const char *filename, int lineno, const c
# else /* !DEBUG_THREADS */
# define DEADLOCK_AVOIDANCE(lock) \
ast_mutex_unlock ( lock ) ; \
usleep ( 1 ) ; \
ast_mutex_lock ( lock ) ;
do { \
int __res ; \
if ( ! ( __res = ast_mutex_unlock ( lock ) ) ) { \
usleep ( 1 ) ; \
ast_mutex_lock ( lock ) ; \
} else { \
ast_log ( LOG_WARNING , " Failed to unlock mutex '%s' (%s). I will NOT try to relock. {{{ THIS IS A BUG. }}} \n " , # lock , strerror ( __res ) ) ; \
} \
} while ( 0 )
typedef pthread_mutex_t ast_mutex_t ;
@ -1367,7 +1384,7 @@ AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
# define ast_channel_lock(x) ast_mutex_lock(&x->lock)
/*! \brief Unlock a channel. If DEBUG_CHANNEL_LOCKS is defined
in the Makefile , print relevant output for debugging */
# define ast_channel_unlock(x) ast_mutex_unlock(&x->lock)
# define ast_channel_unlock(x) ast_mutex_unlock(&x->lock)
/*! \brief Try locking a channel. If DEBUG_CHANNEL_LOCKS is defined
in the Makefile , print relevant output for debugging */
# define ast_channel_trylock(x) ast_mutex_trylock(&x->lock)
@ -1389,7 +1406,7 @@ int __ast_channel_unlock(struct ast_channel *chan, const char *file, int lineno,
# define ast_channel_trylock(a) __ast_channel_trylock(a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
/*! \brief Lock AST channel (and print debugging output)
\ note You need to enable DEBUG_CHANNEL_LOCKS for this function */
int __ast_channel_trylock ( struct ast_channel * chan , const char * file , int lineno , const char * func ) ;
int __ast_channel_trylock ( struct ast_channel * chan , const char * file , int lineno , const char * func ) attribute_warn_unused_result ;
# endif
# endif /* _ASTERISK_LOCK_H */