]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
asterisk: Audit locking of channel when manipulating flags.
authorJoshua Colp <jcolp@digium.com>
Sat, 13 May 2017 16:40:00 +0000 (16:40 +0000)
committerJoshua Colp <jcolp@digium.com>
Tue, 16 May 2017 14:25:23 +0000 (14:25 +0000)
When manipulating flags on a channel the channel has to be
locked to guarantee that nothing else is also manipulating
the flags. This change introduces locking where necessary to
guarantee this. It also adds helper functions that manipulate
channel flags and lock to reduce repeated code.

ASTERISK-26789

Change-Id: I489280662dba0f4c50981bfc5b5a7073fef2db10

15 files changed:
apps/app_chanspy.c
apps/app_dial.c
apps/app_disa.c
apps/app_dumpchan.c
apps/app_externalivr.c
include/asterisk/channel.h
main/autoservice.c
main/bridge_after.c
main/bridge_channel.c
main/channel.c
main/file.c
main/manager.c
main/pbx.c
res/res_agi.c
res/res_musiconhold.c

index 4814f4ce5db4ce75bb6efd201da7f91cdb98ca99..354b9ea7d35ea7e7eb65295bb1f065868cb5232b 100644 (file)
@@ -693,9 +693,7 @@ static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_auto
                }
        }
 
-       ast_channel_lock(chan);
-       ast_set_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY);
-       ast_channel_unlock(chan);
+       ast_channel_set_flag(chan, AST_FLAG_END_DTMF_ONLY);
 
        csth.volfactor = *volfactor;
 
@@ -825,9 +823,7 @@ static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_auto
        else
                ast_deactivate_generator(chan);
 
-       ast_channel_lock(chan);
-       ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY);
-       ast_channel_unlock(chan);
+       ast_channel_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
 
        if (ast_test_flag(flags, OPTION_WHISPER | OPTION_BARGE | OPTION_DTMF_SWITCH_MODES)) {
                ast_audiohook_lock(&csth.whisper_audiohook);
@@ -921,7 +917,7 @@ static int common_exec(struct ast_channel *chan, struct ast_flags *flags,
        if (ast_channel_state(chan) != AST_STATE_UP)
                ast_answer(chan);
 
-       ast_set_flag(ast_channel_flags(chan), AST_FLAG_SPYING); /* so nobody can spy on us while we are spying */
+       ast_channel_set_flag(chan, AST_FLAG_SPYING);
 
        waitms = 100;
 
@@ -934,7 +930,7 @@ static int common_exec(struct ast_channel *chan, struct ast_flags *flags,
                        if (!res)
                                res = ast_waitstream(chan, "");
                        else if (res < 0) {
-                               ast_clear_flag(ast_channel_flags(chan), AST_FLAG_SPYING);
+                               ast_channel_clear_flag(chan, AST_FLAG_SPYING);
                                break;
                        }
                        if (!ast_strlen_zero(exitcontext)) {
@@ -977,7 +973,7 @@ static int common_exec(struct ast_channel *chan, struct ast_flags *flags,
                res = ast_waitfordigit(chan, waitms);
                if (res < 0) {
                        iter = ast_channel_iterator_destroy(iter);
-                       ast_clear_flag(ast_channel_flags(chan), AST_FLAG_SPYING);
+                       ast_channel_clear_flag(chan, AST_FLAG_SPYING);
                        break;
                }
                if (!ast_strlen_zero(exitcontext)) {
@@ -1196,7 +1192,7 @@ static int common_exec(struct ast_channel *chan, struct ast_flags *flags,
        }
 exit:
 
-       ast_clear_flag(ast_channel_flags(chan), AST_FLAG_SPYING);
+       ast_channel_clear_flag(chan, AST_FLAG_SPYING);
 
        ast_channel_setoption(chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0);
 
index 79e2a9b0bb79dc33cec3099f1400b53c973a60d0..847a095f44a77d9984bd07167168392af8284da1 100644 (file)
@@ -2855,7 +2855,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
                                ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", opt_args[OPT_ARG_ANNOUNCE]);
                        }
 
-                       ast_set_flag(ast_channel_flags(peer), AST_FLAG_END_DTMF_ONLY);
+                       ast_channel_set_flag(peer, AST_FLAG_END_DTMF_ONLY);
                        while (ast_channel_stream(peer)) {
                                int ms;
 
@@ -2919,13 +2919,13 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
                                }
                                ast_sched_runq(ast_channel_sched(peer));
                        }
-                       ast_clear_flag(ast_channel_flags(peer), AST_FLAG_END_DTMF_ONLY);
+                       ast_channel_clear_flag(peer, AST_FLAG_END_DTMF_ONLY);
                }
 
                if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
                        /* 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_clear_flag(chan, AST_FLAG_OUTGOING);
 
                        ast_replace_subargument_delimiter(opt_args[OPT_ARG_GOTO]);
                        ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
index 8dc61ff64c55ec9754a31dc7f7b6b537100f6a79..cceb5541dda83356f366c1e3141844e3d54c8481 100644 (file)
@@ -208,7 +208,7 @@ static int disa_exec(struct ast_channel *chan, const char *data)
 
        play_dialtone(chan, args.mailbox);
 
-       ast_set_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY);
+       ast_channel_set_flag(chan, AST_FLAG_END_DTMF_ONLY);
 
        for (;;) {
                  /* if outa time, give em reorder */
@@ -224,7 +224,7 @@ static int disa_exec(struct ast_channel *chan, const char *data)
                }
 
                if (!(f = ast_read(chan))) {
-                       ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY);
+                       ast_channel_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
                        return -1;
                }
 
@@ -232,7 +232,7 @@ static int disa_exec(struct ast_channel *chan, const char *data)
                        if (f->data.uint32)
                                ast_channel_hangupcause_set(chan, f->data.uint32);
                        ast_frfree(f);
-                       ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY);
+                       ast_channel_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
                        return -1;
                }
 
@@ -261,7 +261,7 @@ static int disa_exec(struct ast_channel *chan, const char *data)
                                                fp = fopen(args.passcode,"r");
                                                if (!fp) {
                                                        ast_log(LOG_WARNING,"DISA password file %s not found on chan %s\n",args.passcode,ast_channel_name(chan));
-                                                       ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY);
+                                                       ast_channel_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
                                                        return -1;
                                                }
                                                pwline[0] = 0;
@@ -357,7 +357,7 @@ static int disa_exec(struct ast_channel *chan, const char *data)
                }
        }
 
-       ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY);
+       ast_channel_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
 
        if (k == 3) {
                int recheck = 0;
index 0789ce06eb80c1b93ecceffef15338072f319bfd..bec7788170d811e405dd0d1f1c2cf693dc0f7ae7 100644 (file)
@@ -88,8 +88,6 @@ static int serialize_showchan(struct ast_channel *c, char *buf, size_t size)
 
        ast_channel_lock(c);
        bridge = ast_channel_get_bridge(c);
-       ast_channel_unlock(c);
-
        snprintf(buf,size,
                "Name=               %s\n"
                "Type=               %s\n"
@@ -166,7 +164,7 @@ static int serialize_showchan(struct ast_channel *c, char *buf, size_t size)
                ast_channel_appl(c) ? ast_channel_appl(c) : "(N/A)",
                ast_channel_data(c) ? S_OR(ast_channel_data(c), "(Empty)") : "(None)",
                (ast_test_flag(ast_channel_flags(c), AST_FLAG_BLOCKING) ? ast_channel_blockproc(c) : "(Not Blocking)"));
-
+       ast_channel_unlock(c);
        ao2_cleanup(bridge);
        return 0;
 }
index c2224b44b663b2f91f6c6e3ce3dac04548b9e755..84267a5ea49ccbaefce698e9432639e2940864b6 100644 (file)
@@ -642,9 +642,9 @@ static int eivr_comm(struct ast_channel *chan, struct ivr_localuser *u,
        waitfds[0] = ast_iostream_get_fd(eivr_commands);
        waitfds[1] = eivr_errors ? ast_iostream_get_fd(eivr_errors) : -1;
 
-       while (1) {
-               if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)) {
-                       ast_chan_log(LOG_ERROR, chan, "Is a zombie\n");
+       while (1) {
+               if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)) {
+                       ast_chan_log(LOG_ERROR, chan, "Is a zombie\n");
                        break;
                }
                if (!hangup_info_sent && !(ast_test_flag(&flags, run_dead)) && ast_check_hangup(chan)) {
index fd339d97483cba47232d9cdc04a4cfd0cb070cf9..005803d5cad6c17c24ba72066bcf182243e1485a 100644 (file)
@@ -4436,6 +4436,31 @@ void ast_channel_dialed_causes_clear(const struct ast_channel *chan);
 
 struct ast_flags *ast_channel_flags(struct ast_channel *chan);
 
+/*!
+ * \since 13.17.0
+ * \brief Set a flag on a channel
+ *
+ * \param chan The channel to set the flag on
+ * \param flag The flag to set
+ *
+ * \note This will lock the channel internally. If the channel is already
+ * locked it is still safe to call.
+ */
+
+void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag);
+
+/*!
+ * \since 13.17.0
+ * \param Clear a flag on a channel
+ *
+ * \param chan The channel to clear the flag from
+ * \param flag The flag to clear
+ *
+ * \note This will lock the channel internally. If the channel is already
+ * locked it is still safe to call.
+ */
+void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag);
+
 /*!
  * \since 12.4.0
  * \brief Return whether or not any manager variables have been set
index 11c9eab969d85c90346bb9254c14f94eefa900d7..d1a0156ab46ef59d692fca72e0d525372c40632e 100644 (file)
@@ -295,11 +295,11 @@ int ast_autoservice_stop(struct ast_channel *chan)
                res = 0;
        }
 
+       ast_channel_lock(chan);
        if (!as->orig_end_dtmf_flag) {
                ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY);
        }
 
-       ast_channel_lock(chan);
        while ((f = AST_LIST_REMOVE_HEAD(&as->deferred_frames, frame_list))) {
                if (!((1 << f->frametype) & as->ignore_frame_types)) {
                        ast_queue_frame_head(chan, f);
index d649717e2b8a630b2006e254dce9ddad3f5de7ea..d4aec75d0fe2e33c02d325f5df5a210f1f3db334 100644 (file)
@@ -482,7 +482,7 @@ int ast_bridge_setup_after_goto(struct ast_channel *chan)
                }
        } else if (!ast_check_hangup(chan)) {
                /* Clear the outgoing flag */
-               ast_clear_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING);
+               ast_channel_clear_flag(chan, AST_FLAG_OUTGOING);
 
                if (after_bridge->specific) {
                        goto_failed = ast_explicit_goto(chan, after_bridge->context,
index 4f166fff06f9d84562c1d7566773fa2c355cd316..c6ea222eeb87e0b11cc601d38b56c97264787c6d 100644 (file)
@@ -2101,7 +2101,7 @@ void bridge_channel_internal_pull(struct ast_bridge_channel *bridge_channel)
            && (ast_channel_is_leaving_bridge(bridge_channel->chan)
                || bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT)) {
                ast_debug(2, "Channel %s will survive this bridge; clearing outgoing (dialed) flag\n", ast_channel_name(bridge_channel->chan));
-               ast_clear_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_OUTGOING);
+               ast_channel_clear_flag(bridge_channel->chan, AST_FLAG_OUTGOING);
        }
 
        bridge->reconfigured = 1;
index 099e6f65abb486e84c17091dffde4cad3dafe41d..1f97e651c32e4b5748b77d41404f23dfe175dd32 100644 (file)
@@ -1288,8 +1288,10 @@ int ast_channel_defer_dtmf(struct ast_channel *chan)
        int pre = 0;
 
        if (chan) {
+               ast_channel_lock(chan);
                pre = ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF);
                ast_set_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF);
+               ast_channel_unlock(chan);
        }
        return pre;
 }
@@ -1297,8 +1299,9 @@ int ast_channel_defer_dtmf(struct ast_channel *chan)
 /*! \brief Unset defer DTMF flag on channel */
 void ast_channel_undefer_dtmf(struct ast_channel *chan)
 {
-       if (chan)
-               ast_clear_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF);
+       if (chan) {
+               ast_channel_clear_flag(chan, AST_FLAG_DEFER_DTMF);
+       }
 }
 
 struct ast_channel *ast_channel_callback(ao2_callback_data_fn *cb_fn, void *arg,
@@ -3223,7 +3226,7 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in
                return -1;
 
        /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */
-       ast_set_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+       ast_channel_set_flag(c, AST_FLAG_END_DTMF_ONLY);
 
        /* Wait for a digit, no more than timeout_ms milliseconds total.
         * Or, wait indefinitely if timeout_ms is <0.
@@ -3242,12 +3245,12 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in
                        if (errno == 0 || errno == EINTR)
                                continue;
                        ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
-                       ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+                       ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
                        return -1;
                } else if (outfd > -1) {
                        /* The FD we were watching has something waiting */
                        ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n");
-                       ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+                       ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
                        return 1;
                } else if (rchan) {
                        int res;
@@ -3261,13 +3264,13 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in
                        case AST_FRAME_DTMF_END:
                                res = f->subclass.integer;
                                ast_frfree(f);
-                               ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+                               ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
                                return res;
                        case AST_FRAME_CONTROL:
                                switch (f->subclass.integer) {
                                case AST_CONTROL_HANGUP:
                                        ast_frfree(f);
-                                       ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+                                       ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
                                        return -1;
                                case AST_CONTROL_STREAM_STOP:
                                case AST_CONTROL_STREAM_SUSPEND:
@@ -3278,7 +3281,7 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in
                                         * that perform stream control will handle this. */
                                        res = f->subclass.integer;
                                        ast_frfree(f);
-                                       ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+                                       ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
                                        return res;
                                case AST_CONTROL_PVT_CAUSE_CODE:
                                case AST_CONTROL_RINGING:
@@ -3313,7 +3316,7 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in
                }
        }
 
-       ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+       ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
 
        return 0; /* Time is up */
 }
@@ -5709,9 +5712,9 @@ struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_chan
        } else if (caller) { /* no outgoing helper so use caller if available */
                call_forward_inherit(new_chan, caller, orig);
        }
-       ast_set_flag(ast_channel_flags(new_chan), AST_FLAG_ORIGINATED);
 
        ast_channel_lock_both(orig, new_chan);
+       ast_channel_set_flag(new_chan, AST_FLAG_ORIGINATED);
        pbx_builtin_setvar_helper(new_chan, "FORWARDERNAME", forwarder);
        ast_party_connected_line_copy(ast_channel_connected(new_chan), ast_channel_connected(orig));
        ast_party_redirecting_copy(ast_channel_redirecting(new_chan), ast_channel_redirecting(orig));
@@ -10947,3 +10950,17 @@ int ast_channel_stream_topology_changed(struct ast_channel *chan, struct ast_str
 
        return ast_channel_tech(chan)->indicate(chan, AST_CONTROL_STREAM_TOPOLOGY_CHANGED, topology, sizeof(topology));
 }
+
+void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag)
+{
+       ast_channel_lock(chan);
+       ast_set_flag(ast_channel_flags(chan), flag);
+       ast_channel_unlock(chan);
+}
+
+void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
+{
+       ast_channel_lock(chan);
+       ast_clear_flag(ast_channel_flags(chan), flag);
+       ast_channel_unlock(chan);
+}
index fb4ede6c88ba486f6fe8a5f03e93517550263286..41131f9eebc3dbc151157dbea8b4d3a593143c3b 100644 (file)
@@ -1543,7 +1543,7 @@ static int waitstream_core(struct ast_channel *c,
                reverse = "";
 
        /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */
-       ast_set_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+       ast_channel_set_flag(c, AST_FLAG_END_DTMF_ONLY);
 
        if (ast_test_flag(ast_channel_flags(c), AST_FLAG_MASQ_NOSTREAM))
                orig_chan_name = ast_strdupa(ast_channel_name(c));
@@ -1575,7 +1575,7 @@ static int waitstream_core(struct ast_channel *c,
                        res = ast_waitfor(c, ms);
                        if (res < 0) {
                                ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
-                               ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+                               ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
                                return res;
                        }
                } else {
@@ -1586,11 +1586,11 @@ static int waitstream_core(struct ast_channel *c,
                                if (errno == EINTR)
                                        continue;
                                ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
-                               ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+                               ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
                                return -1;
                        } else if (outfd > -1) { /* this requires cmdfd set */
                                /* The FD we were watching has something waiting */
-                               ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+                               ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
                                return 1;
                        }
                        /* if rchan is set, it is 'c' */
@@ -1599,7 +1599,7 @@ static int waitstream_core(struct ast_channel *c,
                if (res > 0) {
                        struct ast_frame *fr = ast_read(c);
                        if (!fr) {
-                               ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+                               ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
                                return -1;
                        }
                        switch (fr->frametype) {
@@ -1610,7 +1610,7 @@ static int waitstream_core(struct ast_channel *c,
                                                S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
                                                res = fr->subclass.integer;
                                                ast_frfree(fr);
-                                               ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+                                               ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
                                                return res;
                                        }
                                } else {
@@ -1626,7 +1626,7 @@ static int waitstream_core(struct ast_channel *c,
                                                        "Break");
 
                                                ast_frfree(fr);
-                                               ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+                                               ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
                                                return res;
                                        }
                                }
@@ -1643,7 +1643,7 @@ static int waitstream_core(struct ast_channel *c,
                                                "Break");
                                        res = fr->subclass.integer;
                                        ast_frfree(fr);
-                                       ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+                                       ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
                                        return res;
                                case AST_CONTROL_STREAM_REVERSE:
                                        if (!skip_ms) {
@@ -1661,7 +1661,7 @@ static int waitstream_core(struct ast_channel *c,
                                case AST_CONTROL_BUSY:
                                case AST_CONTROL_CONGESTION:
                                        ast_frfree(fr);
-                                       ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+                                       ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
                                        return -1;
                                case AST_CONTROL_RINGING:
                                case AST_CONTROL_ANSWER:
@@ -1698,7 +1698,7 @@ static int waitstream_core(struct ast_channel *c,
                ast_sched_runq(ast_channel_sched(c));
        }
 
-       ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
+       ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
 
        return (err || ast_channel_softhangup_internal_flag(c)) ? -1 : 0;
 }
index c592fbd37a95ec0697ca6ddc60ab229c62d51eae..dfb0d96c93d03ebc8ac020ee1183d2bcce678c9d 100644 (file)
@@ -4847,14 +4847,10 @@ static int action_redirect(struct mansession *s, const struct message *m)
 
        /* Release the bridge wait. */
        if (chan1_wait) {
-               ast_channel_lock(chan);
-               ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT);
-               ast_channel_unlock(chan);
+               ast_channel_clear_flag(chan, AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT);
        }
        if (chan2_wait) {
-               ast_channel_lock(chan2);
-               ast_clear_flag(ast_channel_flags(chan2), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT);
-               ast_channel_unlock(chan2);
+               ast_channel_clear_flag(chan, AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT);
        }
 
        chan2 = ast_channel_unref(chan2);
index 28027c06b8ac38d4bb20903d170fbcbe26f8b8cd..ccfba054e7c0ebcb383b983b59fd250aa2277b9a 100644 (file)
@@ -4300,8 +4300,10 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
        ast_channel_pbx(c)->rtimeoutms = 10000;
        ast_channel_pbx(c)->dtimeoutms = 5000;
 
+       ast_channel_lock(c);
        autoloopflag = ast_test_flag(ast_channel_flags(c), AST_FLAG_IN_AUTOLOOP);       /* save value to restore at the end */
        ast_set_flag(ast_channel_flags(c), AST_FLAG_IN_AUTOLOOP);
+       ast_channel_unlock(c);
 
        if (ast_strlen_zero(ast_channel_exten(c))) {
                /* If not successful fall back to 's' - but only if there is no given exten  */
@@ -4546,8 +4548,10 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
                ast_pbx_hangup_handler_run(c);
        }
 
+       ast_channel_lock(c);
        ast_set2_flag(ast_channel_flags(c), autoloopflag, AST_FLAG_IN_AUTOLOOP);
        ast_clear_flag(ast_channel_flags(c), AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */
+       ast_channel_unlock(c);
        pbx_destroy(ast_channel_pbx(c));
        ast_channel_pbx_set(c, NULL);
 
index 557f34971528f71b11fd9621e64da73e45dce532..dd341141a345e2c9fe5af886300804586c27ce8f 100644 (file)
@@ -3119,12 +3119,14 @@ static int handle_exec(struct ast_channel *chan, AGI *agi, int argc, const char
        ast_verb(3, "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argc >= 3 ? argv[2] : "");
 
        if ((app_to_exec = pbx_findapp(argv[1]))) {
+               ast_channel_lock(chan);
                if (!(workaround = ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS))) {
                        ast_set_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS);
                }
+               ast_channel_unlock(chan);
                res = pbx_exec(chan, app_to_exec, argc == 2 ? "" : argv[2]);
                if (!workaround) {
-                       ast_clear_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS);
+                       ast_channel_clear_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS);
                }
        } else {
                ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]);
index 71f4691af261c18cb7e9cf46e28b0cf08a20fbde..be50e9cee2b451da6f30531befb93356a523c541 100644 (file)
@@ -1558,8 +1558,10 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con
                }
        }
        if (!res) {
+               ast_channel_lock(chan);
                ast_channel_latest_musicclass_set(chan, mohclass->name);
                ast_set_flag(ast_channel_flags(chan), AST_FLAG_MOH);
+               ast_channel_unlock(chan);
        }
 
        mohclass = mohclass_unref(mohclass, "unreffing local reference to mohclass in local_ast_moh_start");
@@ -1569,10 +1571,10 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con
 
 static void local_ast_moh_stop(struct ast_channel *chan)
 {
-       ast_clear_flag(ast_channel_flags(chan), AST_FLAG_MOH);
        ast_deactivate_generator(chan);
 
        ast_channel_lock(chan);
+       ast_clear_flag(ast_channel_flags(chan), AST_FLAG_MOH);
        if (ast_channel_music_state(chan)) {
                if (ast_channel_stream(chan)) {
                        ast_closestream(ast_channel_stream(chan));