summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2013-11-01 12:33:09 +0000
committerJoshua Colp <jcolp@digium.com>2013-11-01 12:33:09 +0000
commit4053f36a71fcb0d8354a9023c9514d51c0011892 (patch)
tree94cf956eeb286f6e378328b15f8ef12daa7310bd
parentd17a780333fc007fdfcd75282a9c4ee032894f2c (diff)
res_ari_channels: Fix a deadlock when originating multiple channels close to eachother.
If a Stasis application is specified an implicit subscription is done on the originated channel. This was previously done with the channel lock held which is dangerous as the underlying code locks the container and iterates items. This change releases the lock on the originated channel before subscribing occurs. (closes issue ASTERISK-22768) Reported by: Matt Jordan Review: https://reviewboard.asterisk.org/r/2979/ ........ Merged revisions 402346 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@402347 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--include/asterisk/stasis_app.h2
-rw-r--r--res/ari/resource_channels.c6
2 files changed, 5 insertions, 3 deletions
diff --git a/include/asterisk/stasis_app.h b/include/asterisk/stasis_app.h
index b11670ac5..749f8ed69 100644
--- a/include/asterisk/stasis_app.h
+++ b/include/asterisk/stasis_app.h
@@ -140,6 +140,8 @@ enum stasis_app_subscribe_res {
* after adding the subscription.
*
* \return \ref stasis_app_subscribe_res return code.
+ *
+ * \note Do not hold any channel locks if subscribing to a channel.
*/
enum stasis_app_subscribe_res stasis_app_subscribe(const char *app_name,
const char **event_source_uris, int event_sources_count,
diff --git a/res/ari/resource_channels.c b/res/ari/resource_channels.c
index a00b29532..10d190534 100644
--- a/res/ari/resource_channels.c
+++ b/res/ari/resource_channels.c
@@ -642,6 +642,9 @@ void ast_ari_originate(struct ast_variable *headers,
return;
}
+ snapshot = ast_channel_snapshot_create(chan);
+ ast_channel_unlock(chan);
+
if (!ast_strlen_zero(args->app)) {
/* channel: + channel ID + null terminator */
char uri[9 + strlen(ast_channel_uniqueid(chan))];
@@ -651,10 +654,7 @@ void ast_ari_originate(struct ast_variable *headers,
stasis_app_subscribe(args->app, uris, 1, NULL);
}
- snapshot = ast_channel_snapshot_create(chan);
ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot));
-
- ast_channel_unlock(chan);
ast_channel_unref(chan);
}