]> 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:01 +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 608eb6be185255ed0efbbcdae8d6dfe82c8f0f23..2a472bf44090887d59cc0b847fd301d8f0e588f2 100644 (file)
@@ -676,9 +676,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;
 
@@ -808,9 +806,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);
@@ -904,7 +900,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;
 
@@ -917,7 +913,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)) {
@@ -960,7 +956,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)) {
@@ -1179,7 +1175,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 250340579f8edcaaa46c52d05c6feb4a550d0c17..9f77cd880d6d92b3c6e436a421c1ef3b9147657c 100644 (file)
@@ -2870,7 +2870,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;
 
@@ -2934,13 +2934,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 824e8fe55de5323f0c6c1c89cbae54e0fe76e41b..dbdad94bec3d66704bf9ba324bd7d2a84ce06db1 100644 (file)
@@ -210,7 +210,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 */
@@ -226,7 +226,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;
                }
 
@@ -234,7 +234,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;
                }
 
@@ -263,7 +263,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;
@@ -359,7 +359,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 1a5a4469a507838d9d2c5e9a614d054881e83afc..14164388d755a9c41147af0bbb726b7e2e8af5b9 100644 (file)
@@ -90,8 +90,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"
@@ -168,7 +166,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 9cb8839db7b73b00573fde6db5ae2931c9259c98..b661a2ec90e57226c8a9b5ed4f49c591283f8573 100644 (file)
@@ -645,9 +645,9 @@ static int eivr_comm(struct ast_channel *chan, struct ivr_localuser *u,
                setvbuf(eivr_errors, NULL, _IONBF, 0);
        }
 
-       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 9acd820e537236a735193825190e03331da591e2..393c020fc9065b9f891b2a9a20f7534abcdc0373 100644 (file)
@@ -4329,6 +4329,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 305ab23b10a64cd802ed8b8fa626e3d14402aba3..f353f0e0cf921c035098ad00513dd4ae52453995 100644 (file)
@@ -300,11 +300,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 a41f8a5483f3eab0582985a16c6f078efe4d5a4a..1208b57b8f20428b20cfe04baf9c640b74f8478c 100644 (file)
@@ -484,7 +484,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 b466b3c6adab10b4e1433af8d39c79fb95d862bd..eba5ae40aeb81ad2abb6cc963660108dd84490d2 100644 (file)
@@ -2092,7 +2092,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 4192c00f201a426708af5728e30c92717ae9f052..5aaeab9d2957dc69bb251e17a1ceab5db6d9e240 100644 (file)
@@ -1296,8 +1296,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;
 }
@@ -1305,8 +1307,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,
@@ -3518,7 +3521,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.
@@ -3537,12 +3540,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;
@@ -3556,13 +3559,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:
@@ -3573,7 +3576,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:
@@ -3608,7 +3611,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 */
 }
@@ -5873,9 +5876,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));
@@ -10996,3 +10999,18 @@ enum ast_channel_error ast_channel_errno(void)
 {
        return ast_channel_internal_errno();
 }
+
+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 11617fb7faa17bddb259d6ce6b2f2906244743d0..bb1db3ee647ab977a282d81d37ed76478841a699 100644 (file)
@@ -1545,7 +1545,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));
@@ -1577,7 +1577,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 {
@@ -1588,11 +1588,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' */
@@ -1601,7 +1601,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) {
@@ -1612,7 +1612,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 {
@@ -1628,7 +1628,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;
                                        }
                                }
@@ -1645,7 +1645,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) {
@@ -1663,7 +1663,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:
@@ -1700,7 +1700,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 6f57f056edc8f35f89b47da25744861a0a75a9a8..6db52b8b4d0fd76f52267a77fa6677fd309e6362 100644 (file)
@@ -4819,14 +4819,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 b4089abd710ac1ac277957d8765cc3c31b3bf869..cfc5f7f9f1cc4579fef462be6a9c13d725687aac 100644 (file)
@@ -4257,8 +4257,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  */
@@ -4503,8 +4505,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 cd0d621eb18f9368f860ebc5f8c1bd9bf1705226..4b60daedfbca93fc9b3ddb3bec4d07259733c036 100644 (file)
@@ -3121,12 +3121,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 9d6194170c74a6b5f4ba248eec4990d19bfbbdfd..c52c964288de21731d322f8c51a7fb2b9e739f0c 100644 (file)
@@ -1548,8 +1548,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");
@@ -1559,10 +1561,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));