]> 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:26:40 +0000 (09:26 -0500)
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 9ef7477e6f53a981b5068ad1f69bb9cfd7c74723..daa684e38a8ca97831fd9b7b63c32e3e7c87ba29 100644 (file)
@@ -695,9 +695,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;
 
@@ -827,9 +825,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);
@@ -923,7 +919,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;
 
@@ -936,7 +932,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)) {
@@ -979,7 +975,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)) {
@@ -1198,7 +1194,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 5e0f172a8f046ee50e8e2ba7d1c456cd9731a44a..3648d3e867f40cdaed1a0f9adb669785dc627f80 100644 (file)
@@ -2875,7 +2875,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;
 
@@ -2939,13 +2939,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 ab8d3082f20356b889f84520b43010fd0a010c69..dc59ae5a72d938029443ef3e397d77d4124ab463 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 8b32b93dc1293ad29f86bef09a0f15055d5915da..1c7b0a6159f16ee51056dc7749ede29d1e7d0a70 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 2bb1d8b535352a6132a72e68530698964c957397..c824e91059a1720c67e5a0d2cb6a2b0eea6ce416 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 3acd07774b3364d83f5be5ca66db1f6239646211..820b56d81d21569751123f03a79313ca87592251 100644 (file)
@@ -4309,6 +4309,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 1af052d08891af58be61ba3d31178534add70fc3..3f8b4570a4c666873b43d48996b4b0e3eeab9475 100644 (file)
@@ -297,11 +297,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 e2f14ab611b28b5a9ee8ef0401b4655783d6aaa0..3a8ec797af8eee81b4f05862f6e1cef373c0ae56 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 f92f6bc5815d01bd060a00b3c88e22c532223890..f954688ee696a8b363eb230e458c0e751d07efcd 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 8e7d142bba81a8c1031da491ef4d8c0034be608b..0934d7925bff0f866b642df870b5e96d7c3f1b1a 100644 (file)
@@ -1299,8 +1299,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;
 }
@@ -1308,8 +1310,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));
@@ -11036,3 +11039,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 40e47345c8a3db28e520406fbd971103b00103f2..4239ddd66353babbd8a4b9770f16fbec26a00037 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 6604f6f2bfc353a75213cc66c768149226b1aaa4..7751ef58eb2e5c1c210b383dee5ee49834a7d658 100644 (file)
@@ -4853,14 +4853,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 e1a0c904ed308ee5a79391217db1f22b41ddc72e..0b2c438bc7dce1812caf04de843065a43eb6fd34 100644 (file)
@@ -4299,8 +4299,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  */
@@ -4545,8 +4547,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 d46a019eadf5a86300486712f5e9b24757813700..b391a9b4f45032abab7565d923c2a86b8e24e665 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 af6ed856159540b4019aae9a136c85c700d2054a..a070f31fd762e81c6014190b1d2537bd53879762 100644 (file)
@@ -1560,8 +1560,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");
@@ -1571,10 +1573,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));