CDR: Fix deadlock setting some CDR values.

Setting channel variables with the AMI Originate action caused a deadlock
when you set CDR(amaflags) or CDR(accountcode).  This path has the channel
locked when the CDR function is called.  The CDR function then
synchronously passes the job to a stasis thread.  The stasis handling
function then attempts to lock the channel.  Deadlock results.

* Avoid deadlock by making the CDR function handle setting amaflags and
accountcode directly on the channel rather than passing it off to the CDR
processing code under a stasis thread to do it.

* Made the CHANNEL function and the CDR function process amaflags the same
way.

* Fixed referencing the wrong message type in cdr_prop_write().

ASTERISK-27460

Change-Id: I5eacb47586bc0b8f8ff76a19bd92d1dc38b75e8f
This commit is contained in:
Richard Mudgett
2017-12-05 18:04:47 -06:00
parent 3fc1490bcb
commit 3078b7adc2
2 changed files with 90 additions and 58 deletions

View File

@@ -495,18 +495,17 @@ static int func_channel_write_real(struct ast_channel *chan, const char *functio
ast_bridge_set_after_go_on(chan, ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan), value);
}
} else if (!strcasecmp(data, "amaflags")) {
ast_channel_lock(chan);
int amaflags;
if (isdigit(*value)) {
int amaflags;
sscanf(value, "%30d", &amaflags);
ast_channel_amaflags_set(chan, amaflags);
} else if (!strcasecmp(value,"OMIT")){
ast_channel_amaflags_set(chan, 1);
} else if (!strcasecmp(value,"BILLING")){
ast_channel_amaflags_set(chan, 2);
} else if (!strcasecmp(value,"DOCUMENTATION")){
ast_channel_amaflags_set(chan, 3);
if (sscanf(value, "%30d", &amaflags) != 1) {
amaflags = AST_AMA_NONE;
}
} else {
amaflags = ast_channel_string2amaflag(value);
}
ast_channel_lock(chan);
ast_channel_amaflags_set(chan, amaflags);
ast_channel_unlock(chan);
} else if (!strcasecmp(data, "peeraccount"))
locked_string_field_set(chan, peeraccount, value);