]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_ari_channels: Fix a deadlock when originating multiple channels close to eachother.
authorJoshua Colp <jcolp@digium.com>
Fri, 1 Nov 2013 12:31:51 +0000 (12:31 +0000)
committerJoshua Colp <jcolp@digium.com>
Fri, 1 Nov 2013 12:31:51 +0000 (12:31 +0000)
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/

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/12@402346 65c4cc65-6c06-0410-ace0-fbb531ad65f3

include/asterisk/stasis_app.h
res/ari/resource_channels.c

index b11670ac5dd2704d42657a5362bf4bf47e3aa797..749f8ed694f0ad0208b38bd94c3d0245f4530c2b 100644 (file)
@@ -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,
index a00b295329ebd795b218b3af616913e001508b60..10d190534e6c5fe121afda6b3640c528c6c621ad 100644 (file)
@@ -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);
 }