Reduce channel snapshot creation and publishing by up to 50%.
authorJoshua Colp <jcolp@digium.com>
Wed, 2 Oct 2013 16:23:34 +0000 (16:23 +0000)
committerJoshua Colp <jcolp@digium.com>
Wed, 2 Oct 2013 16:23:34 +0000 (16:23 +0000)
This change introduces the ability to stage channel snapshot
creation and publishing by suppressing the implicit creation
and publishing that some functions have. Once all operations
are executed the staging is marked as done and a single snapshot
is created and published.

Review: https://reviewboard.asterisk.org/r/2889/
........

Merged revisions 400265 from http://svn.asterisk.org/svn/asterisk/branches/12

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

22 files changed:
apps/app_dial.c
channels/chan_alsa.c
channels/chan_console.c
channels/chan_dahdi.c
channels/chan_gtalk.c
channels/chan_iax2.c
channels/chan_jingle.c
channels/chan_mgcp.c
channels/chan_motif.c
channels/chan_pjsip.c
channels/chan_sip.c
channels/chan_skinny.c
channels/chan_unistim.c
channels/sig_pri.c
channels/sig_ss7.c
include/asterisk/channel.h
include/asterisk/stasis_channels.h
main/bridge.c
main/channel.c
main/dial.c
main/pbx.c
main/stasis_channels.c

index cd675fa..2fb7fc9 100644 (file)
@@ -1958,10 +1958,12 @@ static void end_bridge_callback(void *data)
        time(&end);
 
        ast_channel_lock(chan);
+       ast_channel_stage_snapshot(chan);
        snprintf(buf, sizeof(buf), "%d", ast_channel_get_up_time(chan));
        pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf);
        snprintf(buf, sizeof(buf), "%d", ast_channel_get_duration(chan));
        pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf);
+       ast_channel_stage_snapshot_done(chan);
        ast_channel_unlock(chan);
 }
 
@@ -2096,11 +2098,13 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
        struct ast_party_caller caller;
 
        /* Reset all DIAL variables back to blank, to prevent confusion (in case we don't reset all of them). */
+       ast_channel_stage_snapshot(chan);
        pbx_builtin_setvar_helper(chan, "DIALSTATUS", "");
        pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", "");
        pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", "");
        pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", "");
        pbx_builtin_setvar_helper(chan, "DIALEDTIME", "");
+       ast_channel_stage_snapshot_done(chan);
 
        if (ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "Dial requires an argument (technology/resource)\n");
@@ -2431,6 +2435,9 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
                        chanlist_free(tmp);
                        continue;
                }
+
+               ast_channel_stage_snapshot(tc);
+
                ast_channel_get_device_name(tc, device_name, sizeof(device_name));
                if (!ignore_cc) {
                        ast_cc_extension_monitor_add_dialstring(chan, tmp->interface, device_name);
@@ -2540,6 +2547,8 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
                else
                        ast_channel_exten_set(tc, ast_channel_exten(chan));
 
+               ast_channel_stage_snapshot_done(tc);
+
                ast_channel_unlock(tc);
                ast_channel_unlock(chan);
 
@@ -2690,6 +2699,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
                        ast_answer(chan);
 
                strcpy(pa.status, "ANSWER");
+               ast_channel_stage_snapshot(chan);
                pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
                /* Ah ha!  Someone answered within the desired timeframe.  Of course after this
                   we will always return with -1 so that it is hung up properly after the
@@ -2708,6 +2718,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
                }
                ast_channel_unlock(peer);
                pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
+               ast_channel_stage_snapshot_done(chan);
 
                if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
                        ast_debug(1, "app_dial: sendurl=%s.\n", args.url);
@@ -2793,6 +2804,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
                        /* chan and peer are going into the PBX; as such neither are considered
                         * outgoing channels any longer */
                        ast_clear_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING);
+                       ast_channel_stage_snapshot(peer);
                        ast_clear_flag(ast_channel_flags(peer), AST_FLAG_OUTGOING);
 
                        ast_replace_subargument_delimiter(opt_args[OPT_ARG_GOTO]);
@@ -2801,6 +2813,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
                        ast_channel_context_set(peer, ast_channel_context(chan));
                        ast_channel_exten_set(peer, ast_channel_exten(chan));
                        ast_channel_priority_set(peer, ast_channel_priority(chan) + 2);
+                       ast_channel_stage_snapshot_done(peer);
                        if (ast_pbx_start(peer)) {
                                ast_autoservice_chan_hangup_peer(chan, peer);
                        }
index 7f54d6c..f1720ba 100644 (file)
@@ -62,6 +62,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/abstract_jb.h"
 #include "asterisk/musiconhold.h"
 #include "asterisk/poll-compat.h"
+#include "asterisk/stasis_channels.h"
 
 /*! Global jitterbuffer configuration - by default, jb is disabled
  *  \note Values shown here match the defaults shown in alsa.conf.sample */
@@ -580,6 +581,8 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state, const ch
        if (!(tmp = ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, linkedid, 0, "ALSA/%s", indevname)))
                return NULL;
 
+       ast_channel_stage_snapshot(tmp);
+
        ast_channel_tech_set(tmp, &alsa_tech);
        ast_channel_set_fd(tmp, 0, readdev);
        ast_format_set(ast_channel_readformat(tmp), AST_FORMAT_SLINEAR, 0);
@@ -596,6 +599,9 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state, const ch
        p->owner = tmp;
        ast_module_ref(ast_module_info->self);
        ast_jb_configure(tmp, &global_jbconf);
+
+       ast_channel_stage_snapshot_done(tmp);
+
        if (state != AST_STATE_DOWN) {
                if (ast_pbx_start(tmp)) {
                        ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
index 0f4d01e..76571d2 100644 (file)
@@ -76,6 +76,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/musiconhold.h"
 #include "asterisk/callerid.h"
 #include "asterisk/astobj2.h"
+#include "asterisk/stasis_channels.h"
 
 /*! 
  * \brief The sample rate to request from PortAudio 
@@ -427,6 +428,8 @@ static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext,
                return NULL;
        }
 
+       ast_channel_stage_snapshot(chan);
+
        ast_channel_tech_set(chan, &console_tech);
        ast_format_set(ast_channel_readformat(chan), AST_FORMAT_SLINEAR16, 0);
        ast_format_set(ast_channel_writeformat(chan), AST_FORMAT_SLINEAR16, 0);
@@ -440,6 +443,8 @@ static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext,
 
        ast_jb_configure(chan, &global_jbconf);
 
+       ast_channel_stage_snapshot_done(chan);
+
        if (state != AST_STATE_DOWN) {
                if (ast_pbx_start(chan)) {
                        ast_channel_hangupcause_set(chan, AST_CAUSE_SWITCH_CONGESTION);
index 853c5f4..65a9758 100644 (file)
@@ -8910,6 +8910,8 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
                return NULL;
        }
 
+       ast_channel_stage_snapshot(tmp);
+
        if (callid) {
                ast_channel_callid_set(tmp, callid);
        }
@@ -9087,6 +9089,8 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
        for (v = i->vars ; v ; v = v->next)
                pbx_builtin_setvar_helper(tmp, v->name, v->value);
 
+       ast_channel_stage_snapshot_done(tmp);
+
        ast_module_ref(ast_module_info->self);
 
        dahdi_ami_channel_event(i, tmp);
index fc1b75a..a44ca57 100644 (file)
@@ -1149,6 +1149,9 @@ static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i,
                ast_log(LOG_WARNING, "Unable to allocate Gtalk channel structure!\n");
                return NULL;
        }
+
+       ast_channel_stage_snapshot(tmp);
+
        ast_channel_tech_set(tmp, &gtalk_tech);
 
        /* Select our native format based on codec preference until we receive
@@ -1221,6 +1224,9 @@ static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i,
        ast_channel_priority_set(tmp, 1);
        if (i->rtp)
                ast_jb_configure(tmp, &global_jbconf);
+
+       ast_channel_stage_snapshot_done(tmp);
+
        if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
                ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
                ast_channel_hangupcause_set(tmp, AST_CAUSE_SWITCH_CONGESTION);
index b880f5d..6288861 100644 (file)
@@ -116,6 +116,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/bridge.h"
 #include "asterisk/stasis.h"
 #include "asterisk/stasis_system.h"
+#include "asterisk/stasis_channels.h"
 
 #include "iax2/include/iax2.h"
 #include "iax2/include/firmware.h"
@@ -5702,6 +5703,8 @@ static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capab
                return NULL;
        }
 
+       ast_channel_stage_snapshot(tmp);
+
        if ((callid = iaxs[callno]->callid)) {
                ast_channel_callid_set(tmp, callid);
        }
@@ -5799,6 +5802,8 @@ static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capab
                }
        }
 
+       ast_channel_stage_snapshot_done(tmp);
+
        if (state != AST_STATE_DOWN) {
                if (ast_pbx_start(tmp)) {
                        ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
index e5fd025..a8cab62 100644 (file)
@@ -79,6 +79,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/abstract_jb.h"
 #include "asterisk/jabber.h"
 #include "asterisk/jingle.h"
+#include "asterisk/stasis_channels.h"
 
 #define JINGLE_CONFIG "jingle.conf"
 
@@ -862,6 +863,9 @@ static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *
                ast_log(LOG_WARNING, "Unable to allocate Jingle channel structure!\n");
                return NULL;
        }
+
+       ast_channel_stage_snapshot(tmp);
+
        ast_channel_tech_set(tmp, &jingle_tech);
 
        /* Select our native format based on codec preference until we receive
@@ -935,6 +939,9 @@ static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *
        ast_channel_priority_set(tmp, 1);
        if (i->rtp)
                ast_jb_configure(tmp, &global_jbconf);
+
+       ast_channel_stage_snapshot_done(tmp);
+
        if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
                ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
                ast_channel_hangupcause_set(tmp, AST_CAUSE_SWITCH_CONGESTION);
index 8fcdebf..7c91200 100644 (file)
@@ -85,6 +85,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/bridge.h"
 #include "asterisk/features_config.h"
 #include "asterisk/parking.h"
+#include "asterisk/stasis_channels.h"
 
 /*
  * Define to work around buggy dlink MGCP phone firmware which
@@ -1506,6 +1507,7 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state, cons
 
        tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, linkedid, i->accountcode, i->exten, i->context, i->amaflags, "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id);
        if (tmp) {
+               ast_channel_stage_snapshot(tmp);
                ast_channel_tech_set(tmp, &mgcp_tech);
                ast_format_cap_copy(ast_channel_nativeformats(tmp), i->cap);
                if (ast_format_cap_is_empty(ast_channel_nativeformats(tmp))) {
@@ -1566,6 +1568,9 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state, cons
                if (sub->rtp) {
                        ast_jb_configure(tmp, &global_jbconf);
                }
+
+               ast_channel_stage_snapshot_done(tmp);
+
                if (state != AST_STATE_DOWN) {
                        if (ast_pbx_start(tmp)) {
                                ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
index 72118ce..e13c66c 100644 (file)
@@ -76,6 +76,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/astobj.h"
 #include "asterisk/abstract_jb.h"
 #include "asterisk/xmpp.h"
+#include "asterisk/stasis_channels.h"
 
 /*** DOCUMENTATION
        <configInfo name="chan_motif" language="en_US">
@@ -785,6 +786,8 @@ static struct ast_channel *jingle_new(struct jingle_endpoint *endpoint, struct j
                return NULL;
        }
 
+       ast_channel_stage_snapshot(chan);
+
        ast_channel_tech_set(chan, &jingle_tech);
        ast_channel_tech_pvt_set(chan, session);
        jingle_set_owner(session, chan);
@@ -848,6 +851,8 @@ static struct ast_channel *jingle_new(struct jingle_endpoint *endpoint, struct j
 
        ao2_unlock(endpoint);
 
+       ast_channel_stage_snapshot_done(chan);
+
        return chan;
 }
 
index 42e329e..fcca25c 100644 (file)
@@ -577,6 +577,8 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s
                return NULL;
        }
 
+       ast_channel_stage_snapshot(chan);
+
        /* If res_pjsip_session is ever updated to create/destroy ast_sip_session_media
         * during a call such as if multiple same-type stream support is introduced,
         * these will need to be recaptured as well */
@@ -632,6 +634,8 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s
 
        ast_endpoint_add_channel(session->endpoint->persistent, chan);
 
+       ast_channel_stage_snapshot_done(chan);
+
        return chan;
 }
 
index 2a821dd..497fb6e 100644 (file)
@@ -7285,6 +7285,10 @@ static int sip_hangup(struct ast_channel *ast)
                                        } while (sip_pvt_trylock(p));
                                }
 
+                               if (p->rtp || p->vrtp || p->trtp) {
+                                       ast_channel_stage_snapshot(oldowner);
+                               }
+
                                if (p->rtp) {
                                        ast_rtp_instance_set_stats_vars(oldowner, p->rtp);
                                }
@@ -7320,6 +7324,9 @@ static int sip_hangup(struct ast_channel *ast)
                                        }
                                        pbx_builtin_setvar_helper(oldowner, "RTPTEXTQOS", quality);
                                }
+                               if (p->rtp || p->vrtp || p->trtp) {
+                                       ast_channel_stage_snapshot_done(oldowner);
+                               }
 
                                /* Send a hangup */
                                if (ast_channel_state(oldowner) == AST_STATE_UP) {
@@ -8092,6 +8099,8 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
                }
        }
 
+       ast_channel_stage_snapshot(tmp);
+
        /* If we sent in a callid, bind it to the channel. */
        if (callid) {
                ast_channel_callid_set(tmp, callid);
@@ -8287,6 +8296,8 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
                append_history(i, "NewChan", "Channel %s - from %s", ast_channel_name(tmp), i->callid);
        }
 
+       ast_channel_stage_snapshot_done(tmp);
+
        return tmp;
 }
 
@@ -26531,6 +26542,10 @@ static int handle_request_bye(struct sip_pvt *p, struct sip_request *req)
                }
        }
 
+       if ((p->rtp || p->vrtp || p->trtp) && p->owner) {
+               ast_channel_stage_snapshot(p->owner);
+       }
+
        /* Get RTCP quality before end of call */
        if (p->rtp) {
                if (p->do_history) {
@@ -26595,6 +26610,10 @@ static int handle_request_bye(struct sip_pvt *p, struct sip_request *req)
                }
        }
 
+       if ((p->rtp || p->vrtp || p->trtp) && p->owner) {
+               ast_channel_stage_snapshot_done(p->owner);
+       }
+
        stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
        stop_session_timer(p); /* Stop Session-Timer */
 
index 7cf592a..496de18 100644 (file)
@@ -82,6 +82,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/stasis_endpoints.h"
 #include "asterisk/bridge.h"
 #include "asterisk/parking.h"
+#include "asterisk/stasis_channels.h"
 
 /*** DOCUMENTATION
        <manager name="SKINNYdevices" language="en_US">
@@ -5423,6 +5424,7 @@ static struct ast_channel *skinny_new(struct skinny_line *l, struct skinny_subli
                        AST_LIST_INSERT_HEAD(&l->sub, sub, list);
                        //l->activesub = sub;
                }
+               ast_channel_stage_snapshot(tmp);
                ast_channel_tech_set(tmp, &skinny_tech);
                ast_channel_tech_pvt_set(tmp, sub);
                ast_format_cap_copy(ast_channel_nativeformats(tmp), l->cap);
@@ -5496,6 +5498,8 @@ static struct ast_channel *skinny_new(struct skinny_line *l, struct skinny_subli
                for (v = l->chanvars ; v ; v = v->next)
                        pbx_builtin_setvar_helper(tmp, v->name, v->value);
 
+               ast_channel_stage_snapshot_done(tmp);
+
                if (state != AST_STATE_DOWN) {
                        if (ast_pbx_start(tmp)) {
                                ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
index adb5cb9..5238679 100644 (file)
@@ -77,7 +77,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/astdb.h"
 #include "asterisk/features_config.h"
 #include "asterisk/bridge.h"
-
+#include "asterisk/stasis_channels.h"
 
 #define DEFAULTCONTEXT   "default"
 #define DEFAULTCALLERID         "Unknown"
@@ -5563,6 +5563,8 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
                return NULL;
        }
 
+       ast_channel_stage_snapshot(tmp);
+
        ast_format_cap_copy(ast_channel_nativeformats(tmp), l->cap);
        if (ast_format_cap_is_empty(ast_channel_nativeformats(tmp))) {
                ast_format_cap_copy(ast_channel_nativeformats(tmp), global_cap);
@@ -5623,6 +5625,9 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
                }
        }
        ast_channel_priority_set(tmp, 1);
+
+       ast_channel_stage_snapshot_done(tmp);
+
        if (state != AST_STATE_DOWN) {
                if (unistimdebug) {
                        ast_verb(0, "Starting pbx in unistim_new\n");
index 9f40077..5def34c 100644 (file)
@@ -6473,6 +6473,7 @@ static void *pri_dchannel(void *vpri)
                                                ast_mutex_lock(&pri->lock);
                                                sig_pri_lock_private(pri->pvts[chanpos]);
                                                if (c) {
+                                                       ast_channel_stage_snapshot(c);
 #if defined(HAVE_PRI_SUBADDR)
                                                        if (e->ring.calling.subaddress.valid) {
                                                                /* Set Calling Subaddress */
@@ -6557,6 +6558,7 @@ static void *pri_dchannel(void *vpri)
                                                                        PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
 #endif
                                                        }
+                                                       ast_channel_stage_snapshot_done(c);
                                                }
                                                if (c && !ast_pthread_create_detached(&threadid, NULL, pri_ss_thread, pri->pvts[chanpos])) {
                                                        ast_verb(3, "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
@@ -6602,6 +6604,7 @@ static void *pri_dchannel(void *vpri)
                                                         * will do anything with the channel we have just
                                                         * created.
                                                         */
+                                                       ast_channel_stage_snapshot(c);
 #if defined(HAVE_PRI_SUBADDR)
                                                        if (e->ring.calling.subaddress.valid) {
                                                                /* Set Calling Subaddress */
@@ -6670,6 +6673,8 @@ static void *pri_dchannel(void *vpri)
 
                                                        sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.subcmds,
                                                                e->ring.call);
+
+                                                       ast_channel_stage_snapshot_done(c);
                                                }
                                                if (c && !ast_pbx_start(c)) {
                                                        ast_verb(3, "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
index e6e11be..166fda2 100644 (file)
@@ -621,6 +621,8 @@ static void ss7_start_call(struct sig_ss7_chan *p, struct sig_ss7_linkset *links
 
        sig_ss7_set_echocanceller(p, 1);
 
+       ast_channel_stage_snapshot(c);
+
        /*
         * It is reasonably safe to set the following
         * channel variables while the channel private
@@ -700,6 +702,8 @@ static void ss7_start_call(struct sig_ss7_chan *p, struct sig_ss7_linkset *links
                p->generic_name[0] = 0;
        }
 
+       ast_channel_stage_snapshot_done(c);
+
        sig_ss7_unlock_private(p);
        ast_channel_unlock(c);
 
index 24dc53f..e952b93 100644 (file)
@@ -923,6 +923,11 @@ enum {
         * occur.
         */
        AST_FLAG_DEAD = (1 << 24),
+       /*!
+        * Channel snapshot should not be published, it is being staged for an explicit
+        * publish.
+        */
+       AST_FLAG_SNAPSHOT_STAGE = (1 << 25),
 };
 
 /*! \brief ast_bridge_config flags */
index c0b596a..7d9c3ef 100644 (file)
@@ -316,6 +316,22 @@ void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_ty
 
 /*!
  * \since 12
+ * \brief Set flag to indicate channel snapshot is being staged.
+ *
+ * \param chan Channel being staged.
+ */
+void ast_channel_stage_snapshot(struct ast_channel *chan);
+
+/*!
+ * \since 12
+ * \brief Clear flag to indicate channel snapshot is being staged, and publish snapshot.
+ *
+ * \param chan Channel being staged.
+ */
+void ast_channel_stage_snapshot_done(struct ast_channel *chan);
+
+/*!
+ * \since 12
  * \brief Publish a \ref ast_channel_snapshot for a channel.
  *
  * \param chan Channel to publish.
index 19350ed..a972fe7 100644 (file)
@@ -1151,8 +1151,10 @@ static void check_bridge_play_sounds(struct ast_bridge *bridge)
 
 static void update_bridge_vars_set(struct ast_channel *chan, const char *name, const char *pvtid)
 {
+       ast_channel_stage_snapshot(chan);
        pbx_builtin_setvar_helper(chan, "BRIDGEPEER", name);
        pbx_builtin_setvar_helper(chan, "BRIDGEPVTCALLID", pvtid);
+       ast_channel_stage_snapshot_done(chan);
 }
 
 /*!
index e8ce5e0..36528f5 100644 (file)
@@ -876,6 +876,9 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char
                /* Channel structure allocation failure. */
                return NULL;
        }
+
+       ast_channel_stage_snapshot(tmp);
+
        if (!(nativeformats = ast_format_cap_alloc())) {
                ao2_ref(tmp, -1);
                /* format capabilities structure allocation failure */
@@ -1020,7 +1023,7 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char
         * And now, since the channel structure is built, and has its name, let
         * the world know of its existance
         */
-       ast_channel_publish_snapshot(tmp);
+       ast_channel_stage_snapshot_done(tmp);
        return tmp;
 }
 
@@ -7716,8 +7719,12 @@ void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
 {
        struct ast_variable *cur;
 
+       ast_channel_stage_snapshot(chan);
+
        for (cur = vars; cur; cur = cur->next)
                pbx_builtin_setvar_helper(chan, cur->name, cur->value);
+
+       ast_channel_stage_snapshot_done(chan);
 }
 
 static void *silence_generator_alloc(struct ast_channel *chan, void *data)
index 3b720fb..6d796e2 100644 (file)
@@ -286,6 +286,8 @@ static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channe
        cap_request = NULL;
        cap_all_audio = ast_format_cap_destroy(cap_all_audio);
 
+       ast_channel_stage_snapshot(channel->owner);
+
        ast_channel_appl_set(channel->owner, "AppDial2");
        ast_channel_data_set(channel->owner, "(Outgoing Line)");
        ast_publish_channel_state(channel->owner);
@@ -312,6 +314,8 @@ static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channe
                ast_channel_transfercapability_set(channel->owner, ast_channel_transfercapability(chan));
        }
 
+       ast_channel_stage_snapshot_done(channel->owner);
+
        return 0;
 }
 
index 2a41540..6b71c54 100644 (file)
@@ -10050,7 +10050,9 @@ static int pbx_outgoing_attempt(const char *type, struct ast_format_cap *cap, co
                return -1;
        }
 
-       ast_set_variables(dialed, vars);
+       if (vars) {
+               ast_set_variables(dialed, vars);
+       }
 
        if (account) {
                ast_channel_accountcode_set(dialed, account);
index 0fbbf5d..e1a3853 100644 (file)
@@ -600,11 +600,26 @@ struct ast_json *ast_multi_channel_blob_get_json(struct ast_multi_channel_blob *
        return obj->blob;
 }
 
+void ast_channel_stage_snapshot(struct ast_channel *chan)
+{
+       ast_set_flag(ast_channel_flags(chan), AST_FLAG_SNAPSHOT_STAGE);
+}
+
+void ast_channel_stage_snapshot_done(struct ast_channel *chan)
+{
+       ast_clear_flag(ast_channel_flags(chan), AST_FLAG_SNAPSHOT_STAGE);
+       ast_channel_publish_snapshot(chan);
+}
+
 void ast_channel_publish_snapshot(struct ast_channel *chan)
 {
        RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
 
+       if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_SNAPSHOT_STAGE)) {
+               return;
+       }
+
        snapshot = ast_channel_snapshot_create(chan);
        if (!snapshot) {
                return;