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
This commit is contained in:
Richard Mudgett
2013-10-18 16:59:09 +00:00
parent 7352433be5
commit 057d105c5a
4 changed files with 86 additions and 48 deletions

View File

@@ -870,7 +870,7 @@ static void do_forward(struct chanlist *o, struct cause_args *num,
c = o->chan = ast_request(tech, ast_channel_nativeformats(in), in, stuff, &cause);
if (c) {
if (single && !caller_entertained) {
ast_channel_make_compatible(o->chan, in);
ast_channel_make_compatible(in, o->chan);
}
ast_channel_lock_both(in, o->chan);
ast_channel_inherit_variables(in, o->chan);
@@ -1070,7 +1070,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
ast_deactivate_generator(in);
/* If we are calling a single channel, and not providing ringback or music, */
/* then, make them compatible for in-band tone purpose */
if (ast_channel_make_compatible(outgoing->chan, in) < 0) {
if (ast_channel_make_compatible(in, outgoing->chan) < 0) {
/* If these channels can not be made compatible,
* there is no point in continuing. The bridge
* will just fail if it gets that far.