summaryrefslogtreecommitdiff
path: root/res/res_fax.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2013-10-18 16:59:09 +0000
committerRichard Mudgett <rmudgett@digium.com>2013-10-18 16:59:09 +0000
commit057d105c5ab47f132036a6f54c1dae636a9442bd (patch)
tree86bd866ada21eed73dd8228778c0c512ef742e46 /res/res_fax.c
parent7352433be57a41ddf0627cc9cdd4ed386053238a (diff)
Add channel lock protection around translation path setup.
Most callers of ast_channel_make_compatible() happen before the channels enter a two party bridge. With the new bridging framework, two party bridging technologies may also call ast_channel_make_compatible() when there is more than one thread involved with the two channels. * Added channel lock protection in set_format() and ast_channel_make_compatible_helper() when dealing with the channel's native formats while setting up a translation path. * Fixed best_src_fmt and best_dst_fmt usage consistency in ast_channel_make_compatible_helper(). The call to ast_translator_best_choice() got them backwards. * Updated some callers of ast_channel_make_compatible() and the function documentation. There is actually a difference between the two channels passed in. * Fixed the deadlock potential in res_fax.c dealing with ast_channel_make_compatible(). The deadlock potential was already there anyway because res_fax called ast_channel_make_compatible() with chan locked. (closes issue ASTERISK-22542) Reported by: Matt Jordan Review: https://reviewboard.asterisk.org/r/2915/ ........ Merged revisions 401239 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@401240 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_fax.c')
-rw-r--r--res/res_fax.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/res/res_fax.c b/res/res_fax.c
index 6341a55ff..55bd3c6b7 100644
--- a/res/res_fax.c
+++ b/res/res_fax.c
@@ -3057,12 +3057,12 @@ static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct
ast_channel_unlock(chan);
peer = ast_channel_bridge_peer(chan);
- ast_channel_lock(chan);
if (peer) {
ast_set_read_format(peer, &gateway->peer_read_format);
ast_set_read_format(peer, &gateway->peer_write_format);
ast_channel_make_compatible(chan, peer);
}
+ ast_channel_lock(chan);
}
return NULL;
}
@@ -3084,7 +3084,7 @@ static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct
return f;
}
- if (!gateway->bridged && peer) {
+ if (!gateway->bridged) {
/* don't start a gateway if neither channel can handle T.38 */
if (ast_channel_get_t38_state(chan) == T38_STATE_UNAVAILABLE && ast_channel_get_t38_state(peer) == T38_STATE_UNAVAILABLE) {
ast_debug(1, "not starting gateway for %s and %s; neither channel supports T.38\n", ast_channel_name(chan), ast_channel_name(peer));
@@ -3113,10 +3113,12 @@ static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct
ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR);
+ ast_channel_unlock(chan);
ast_set_read_format_by_id(peer, AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(peer, AST_FORMAT_SLINEAR);
ast_channel_make_compatible(chan, peer);
+ ast_channel_lock(chan);
gateway->bridged = 1;
}
@@ -3381,10 +3383,10 @@ static struct ast_frame *fax_detect_framehook(struct ast_channel *chan, struct a
ast_set_read_format(chan, &faxdetect->orig_format);
ast_channel_unlock(chan);
peer = ast_channel_bridge_peer(chan);
- ast_channel_lock(chan);
if (peer) {
ast_channel_make_compatible(chan, peer);
}
+ ast_channel_lock(chan);
return NULL;
case AST_FRAMEHOOK_EVENT_READ:
if (f) {