diff options
author | zuul <zuul@gerrit.asterisk.org> | 2017-03-21 19:47:25 -0500 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2017-03-21 19:47:25 -0500 |
commit | d7ba743329829c5fddb0040708d80461e34e0677 (patch) | |
tree | b7a6ff3f7dc128de62ea3f03fa7b0e49ea27e7e8 /include/asterisk | |
parent | 72ae513f1529a1ac0c55c069db4e06f5732103ef (diff) | |
parent | adad6020beb2aae1f5535bad4c0ff6ea73026848 (diff) |
Merge "autochan/mixmonitor/chanspy: Fix unsafe channel locking and references." into 13
Diffstat (limited to 'include/asterisk')
-rw-r--r-- | include/asterisk/autochan.h | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/include/asterisk/autochan.h b/include/asterisk/autochan.h index 319c203ab..128377b57 100644 --- a/include/asterisk/autochan.h +++ b/include/asterisk/autochan.h @@ -32,6 +32,7 @@ struct ast_autochan { struct ast_channel *chan; AST_LIST_ENTRY(ast_autochan) list; + ast_mutex_t lock; }; /*! @@ -61,19 +62,24 @@ struct ast_autochan { * ast_autochan_channel_lock and ast_autochan_channel_unlock. An attempt to lock * the autochan->chan directly may result in it being changed after you've * retrieved the value of chan, but before you've had a chance to lock it. - * First when chan is locked, the autochan structure is guaranteed to keep the + * While chan is locked, the autochan structure is guaranteed to keep the * same channel. */ +/*! + * \brief Lock the autochan's channel lock. + * + * \note We must do deadlock avoidance because the channel lock is + * superior to the autochan lock in locking order. + */ #define ast_autochan_channel_lock(autochan) \ do { \ - struct ast_channel *autochan_chan = autochan->chan; \ - ast_channel_lock(autochan_chan); \ - if (autochan->chan == autochan_chan) { \ - break; \ + ast_mutex_lock(&(autochan)->lock); \ + while (ast_channel_trylock((autochan)->chan)) { \ + DEADLOCK_AVOIDANCE(&(autochan)->lock); \ } \ - ast_channel_unlock(autochan_chan); \ - } while (1) + ast_mutex_unlock(&(autochan)->lock); \ + } while (0) #define ast_autochan_channel_unlock(autochan) \ ast_channel_unlock(autochan->chan) |