summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorKevin Harwell <kharwell@digium.com>2013-12-18 20:33:37 +0000
committerKevin Harwell <kharwell@digium.com>2013-12-18 20:33:37 +0000
commit28c0cb28d0815e5e59ab99b60ac6b50e1ed9cbae (patch)
treeb42967f4899ba28aea79b9a11827c814b95b62c8 /channels
parent86b5e11607e2e3b7dcfb0b72d41b492ce868f31c (diff)
channel locking: Add locking for channel snapshot creation
Original commit message by mmichelson (asterisk 12 r403311): "This adds channel locks around calls to create channel snapshots as well as other functions which operate on a channel and then end up creating a channel snapshot. Functions that expect the channel to be locked prior to being called have had their documentation updated to indicate such." The above was initially committed and then reverted at r403398. The problem was found to be in core_local.c in the publish_local_bridge_message function. The ast_unreal_lock_all function locks and adds a reference to the returned channels and while they were being unlocked they were not being unreffed when no longer needed. Fixed by unreffing the channels. Also in bridge.c a lock was obtained on "other->chan", but then an attempt was made to unlock "other" and not the previously locked channel. Fixed by unlocking "other->chan" (closes issue ASTERISK-22709) Reported by: John Bigelow ........ Merged revisions 404237 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@404260 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_alsa.c1
-rw-r--r--channels/chan_console.c1
-rw-r--r--channels/chan_dahdi.c6
-rw-r--r--channels/chan_gtalk.c3
-rw-r--r--channels/chan_iax2.c3
-rw-r--r--channels/chan_jingle.c3
-rw-r--r--channels/chan_mgcp.c3
-rw-r--r--channels/chan_misdn.c14
-rw-r--r--channels/chan_motif.c3
-rw-r--r--channels/chan_oss.c1
-rw-r--r--channels/chan_phone.c1
-rw-r--r--channels/chan_pjsip.c3
-rw-r--r--channels/chan_skinny.c3
-rw-r--r--channels/chan_unistim.c5
-rw-r--r--channels/chan_vpb.cc1
-rw-r--r--channels/sig_analog.c4
-rw-r--r--channels/sig_pri.c2
17 files changed, 46 insertions, 11 deletions
diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c
index 1d2d5f9f2..a68a0b2c4 100644
--- a/channels/chan_alsa.c
+++ b/channels/chan_alsa.c
@@ -601,7 +601,6 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state, const ch
ast_jb_configure(tmp, &global_jbconf);
ast_channel_stage_snapshot_done(tmp);
-
ast_channel_unlock(tmp);
if (state != AST_STATE_DOWN) {
diff --git a/channels/chan_console.c b/channels/chan_console.c
index e37b565c5..083af7c06 100644
--- a/channels/chan_console.c
+++ b/channels/chan_console.c
@@ -444,7 +444,6 @@ 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);
-
ast_channel_unlock(chan);
if (state != AST_STATE_DOWN) {
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 636d8863f..e4f1c0c85 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -1667,7 +1667,9 @@ static void publish_dahdichannel(struct ast_channel *chan, int span, const char
return;
}
+ ast_channel_lock(chan);
ast_channel_publish_blob(chan, dahdichannel_type(), blob);
+ ast_channel_unlock(chan);
}
/*!
@@ -9616,6 +9618,7 @@ static void *analog_ss_thread(void *data)
getforward = 0;
} else {
res = tone_zone_play_tone(p->subs[idx].dfd, -1);
+ ast_channel_lock(chan);
ast_channel_exten_set(chan, exten);
if (!ast_strlen_zero(p->cid_num)) {
if (!p->hidecallerid)
@@ -9628,6 +9631,7 @@ static void *analog_ss_thread(void *data)
ast_set_callerid(chan, NULL, p->cid_name, NULL);
}
ast_setstate(chan, AST_STATE_RING);
+ ast_channel_unlock(chan);
dahdi_ec_enable(p);
res = ast_pbx_run(chan);
if (res) {
@@ -10391,8 +10395,10 @@ static void *analog_ss_thread(void *data)
my_handle_notify_message(chan, p, flags, -1);
+ ast_channel_lock(chan);
ast_setstate(chan, AST_STATE_RING);
ast_channel_rings_set(chan, 1);
+ ast_channel_unlock(chan);
p->ringt = p->ringt_base;
res = ast_pbx_run(chan);
if (res) {
diff --git a/channels/chan_gtalk.c b/channels/chan_gtalk.c
index bec440103..60213d3d2 100644
--- a/channels/chan_gtalk.c
+++ b/channels/chan_gtalk.c
@@ -1226,7 +1226,6 @@ static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i,
ast_jb_configure(tmp, &global_jbconf);
ast_channel_stage_snapshot_done(tmp);
-
ast_channel_unlock(tmp);
if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
@@ -1421,7 +1420,9 @@ static int gtalk_newcall(struct gtalk *client, ikspak *pak)
ast_format_cap_joint_copy(p->cap, p->peercap, p->jointcap);
ast_mutex_unlock(&p->lock);
+ ast_channel_lock(chan);
ast_setstate(chan, AST_STATE_RING);
+ ast_channel_unlock(chan);
if (ast_format_cap_is_empty(p->jointcap)) {
ast_log(LOG_WARNING, "Capabilities don't match : us - %s, peer - %s, combined - %s \n", ast_getformatname_multiple(s1, BUFSIZ, p->cap),
ast_getformatname_multiple(s2, BUFSIZ, p->peercap),
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index b89ae824b..447860bd1 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -5804,7 +5804,6 @@ static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capab
}
ast_channel_stage_snapshot_done(tmp);
-
ast_channel_unlock(tmp);
if (state != AST_STATE_DOWN) {
@@ -12237,7 +12236,9 @@ static struct ast_channel *iax2_request(const char *type, struct ast_format_cap
if (c) {
struct ast_format_cap *joint;
if (callid) {
+ ast_channel_lock(c);
ast_channel_callid_set(c, callid);
+ ast_channel_unlock(c);
}
/* Choose a format we can live with */
diff --git a/channels/chan_jingle.c b/channels/chan_jingle.c
index c1c502687..410cb324f 100644
--- a/channels/chan_jingle.c
+++ b/channels/chan_jingle.c
@@ -941,7 +941,6 @@ static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *
ast_jb_configure(tmp, &global_jbconf);
ast_channel_stage_snapshot_done(tmp);
-
ast_channel_unlock(tmp);
if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
@@ -1117,7 +1116,9 @@ static int jingle_newcall(struct jingle *client, ikspak *pak)
}
ast_mutex_unlock(&p->lock);
+ ast_channel_lock(chan);
ast_setstate(chan, AST_STATE_RING);
+ ast_channel_unlock(chan);
res = ast_pbx_start(chan);
switch (res) {
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c
index a6f75e6c3..aaed68fea 100644
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -1570,7 +1570,6 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state, cons
}
ast_channel_stage_snapshot_done(tmp);
-
ast_channel_unlock(tmp);
if (state != AST_STATE_DOWN) {
@@ -3048,6 +3047,7 @@ static void *mgcp_ss(void *data)
} else {
/*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
ast_indicate(chan, -1);
+ ast_channel_lock(chan);
ast_channel_exten_set(chan, p->dtmf_buf);
ast_channel_dialed(chan)->number.str = ast_strdup(p->dtmf_buf);
memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
@@ -3056,6 +3056,7 @@ static void *mgcp_ss(void *data)
p->hidecallerid ? "" : p->cid_name,
ast_channel_caller(chan)->ani.number.valid ? NULL : p->cid_num);
ast_setstate(chan, AST_STATE_RING);
+ ast_channel_unlock(chan);
if (p->dtmfmode & MGCP_DTMF_HYBRID) {
p->dtmfmode |= MGCP_DTMF_INBAND;
ast_indicate(chan, -1);
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index 6dd9adf6a..02b525039 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -5954,7 +5954,9 @@ static int read_config(struct chan_list *ch)
chan_misdn_log(1, port, "read_config: Getting Config\n");
misdn_cfg_get(port, MISDN_CFG_LANGUAGE, lang, sizeof(lang));
+ ast_channel_lock(ast);
ast_channel_language_set(ast, lang);
+ ast_channel_unlock(ast);
misdn_cfg_get(port, MISDN_CFG_MUSICCLASS, ch->mohinterpret, sizeof(ch->mohinterpret));
@@ -6000,7 +6002,9 @@ static int read_config(struct chan_list *ch)
misdn_cfg_get(bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context));
+ ast_channel_lock(ast);
ast_channel_context_set(ast, ch->context);
+ ast_channel_unlock(ast);
#ifdef MISDN_1_2
update_pipeline_config(bc);
@@ -6017,8 +6021,10 @@ static int read_config(struct chan_list *ch)
misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg));
misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg));
chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n", ast_print_group(buf, sizeof(buf), cg), ast_print_group(buf2, sizeof(buf2), pg));
+ ast_channel_lock(ast);
ast_channel_pickupgroup_set(ast, pg);
ast_channel_callgroup_set(ast, cg);
+ ast_channel_unlock(ast);
misdn_cfg_get(port, MISDN_CFG_NAMEDPICKUPGROUP, &npg, sizeof(npg));
misdn_cfg_get(port, MISDN_CFG_NAMEDCALLGROUP, &ncg, sizeof(ncg));
@@ -6031,8 +6037,10 @@ static int read_config(struct chan_list *ch)
ast_free(tmp_str);
}
+ ast_channel_lock(ast);
ast_channel_named_pickupgroups_set(ast, npg);
ast_channel_named_callgroups_set(ast, ncg);
+ ast_channel_unlock(ast);
if (ch->originator == ORG_AST) {
char callerid[BUFFERSIZE + 1];
@@ -6086,7 +6094,9 @@ static int read_config(struct chan_list *ch)
/* Add configured prefix to dialed.number */
misdn_add_number_prefix(bc->port, bc->dialed.number_type, bc->dialed.number, sizeof(bc->dialed.number));
+ ast_channel_lock(ast);
ast_channel_exten_set(ast, bc->dialed.number);
+ ast_channel_unlock(ast);
misdn_cfg_get(bc->port, MISDN_CFG_OVERLAP_DIAL, &ch->overlap_dial, sizeof(ch->overlap_dial));
ast_mutex_init(&ch->overlap_tv_lock);
@@ -10232,8 +10242,10 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
export_ch(chan, bc, ch);
+ ast_channel_lock(ch->ast);
ast_channel_rings_set(ch->ast, 1);
ast_setstate(ch->ast, AST_STATE_RINGING);
+ ast_channel_unlock(ch->ast);
/* Update asterisk channel caller information */
chan_misdn_log(2, bc->port, " --> TON: %s(%d)\n", misdn_to_str_ton(bc->caller.number_type), bc->caller.number_type);
@@ -10532,7 +10544,9 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
}
ast_queue_control(ch->ast, AST_CONTROL_RINGING);
+ ast_channel_lock(ch->ast);
ast_setstate(ch->ast, AST_STATE_RINGING);
+ ast_channel_unlock(ch->ast);
cb_log(7, bc->port, " --> Set State Ringing\n");
diff --git a/channels/chan_motif.c b/channels/chan_motif.c
index 2c2b27007..248f81120 100644
--- a/channels/chan_motif.c
+++ b/channels/chan_motif.c
@@ -852,7 +852,6 @@ static struct ast_channel *jingle_new(struct jingle_endpoint *endpoint, struct j
ao2_unlock(endpoint);
ast_channel_stage_snapshot_done(chan);
-
ast_channel_unlock(chan);
return chan;
@@ -2414,7 +2413,9 @@ static void jingle_action_session_initiate(struct jingle_endpoint *endpoint, str
ao2_link(endpoint->state->sessions, session);
+ ast_channel_lock(chan);
ast_setstate(chan, AST_STATE_RING);
+ ast_channel_unlock(chan);
res = ast_pbx_start(chan);
switch (res) {
diff --git a/channels/chan_oss.c b/channels/chan_oss.c
index 3a52ac9db..92c7374db 100644
--- a/channels/chan_oss.c
+++ b/channels/chan_oss.c
@@ -799,6 +799,7 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx,
c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, linkedid, 0, "Console/%s", o->device + 5);
if (c == NULL)
return NULL;
+ ast_channel_lock(c);
ast_channel_tech_set(c, &oss_tech);
if (o->sounddev < 0)
setformat(o, O_RDWR);
diff --git a/channels/chan_phone.c b/channels/chan_phone.c
index ba14a435e..94a40ca1a 100644
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -862,6 +862,7 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *cntx,
struct ast_format tmpfmt;
tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", i->ext, i->context, linkedid, 0, "Phone/%s", i->dev + 5);
if (tmp) {
+ ast_channel_lock(tmp);
ast_channel_tech_set(tmp, cur_tech);
ast_channel_set_fd(tmp, 0, i->fd);
/* XXX Switching formats silently causes kernel panics XXX */
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index cd209d243..a560d7706 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -364,6 +364,7 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s
return NULL;
}
+
ast_channel_stage_snapshot(chan);
ast_channel_tech_pvt_set(chan, channel);
@@ -1835,9 +1836,11 @@ static void chan_pjsip_incoming_response(struct ast_sip_session *session, struct
switch (status.code) {
case 180:
ast_queue_control(session->channel, AST_CONTROL_RINGING);
+ ast_channel_lock(session->channel);
if (ast_channel_state(session->channel) != AST_STATE_UP) {
ast_setstate(session->channel, AST_STATE_RINGING);
}
+ ast_channel_unlock(session->channel);
break;
case 183:
ast_queue_control(session->channel, AST_CONTROL_PROGRESS);
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index bb270d6a9..49f2c84f6 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -4845,6 +4845,7 @@ static void *skinny_newcall(void *data)
struct skinny_device *d = l->device;
int res = 0;
+ ast_channel_lock(c);
ast_set_callerid(c,
l->hidecallerid ? "" : l->cid_num,
l->hidecallerid ? "" : l->cid_name,
@@ -4858,6 +4859,7 @@ static void *skinny_newcall(void *data)
ast_party_name_init(&ast_channel_connected(c)->id.name);
#endif
ast_setstate(c, AST_STATE_RING);
+ ast_channel_unlock(c);
if (!sub->rtp) {
start_rtp(sub);
}
@@ -5501,7 +5503,6 @@ static struct ast_channel *skinny_new(struct skinny_line *l, struct skinny_subli
pbx_builtin_setvar_helper(tmp, v->name, v->value);
ast_channel_stage_snapshot_done(tmp);
-
ast_channel_unlock(tmp);
if (state != AST_STATE_DOWN) {
diff --git a/channels/chan_unistim.c b/channels/chan_unistim.c
index 21bbbc1e8..bc79f5ee0 100644
--- a/channels/chan_unistim.c
+++ b/channels/chan_unistim.c
@@ -2517,10 +2517,12 @@ static void *unistim_ss(void *data)
int res;
ast_verb(3, "Starting switch on '%s@%s-%d' to %s\n", l->name, l->parent->name, sub->softkey, s->device->phone_number);
+ ast_channel_lock(chan);
ast_channel_exten_set(chan, s->device->phone_number);
+ ast_setstate(chan, AST_STATE_RING);
+ ast_channel_unlock(chan);
ast_copy_string(s->device->redial_number, s->device->phone_number,
sizeof(s->device->redial_number));
- ast_setstate(chan, AST_STATE_RING);
res = ast_pbx_run(chan);
if (res) {
ast_log(LOG_WARNING, "PBX exited non-zero\n");
@@ -5627,7 +5629,6 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
ast_channel_priority_set(tmp, 1);
ast_channel_stage_snapshot_done(tmp);
-
ast_channel_unlock(tmp);
if (state != AST_STATE_DOWN) {
diff --git a/channels/chan_vpb.cc b/channels/chan_vpb.cc
index 39d78cc33..5ea24ccc1 100644
--- a/channels/chan_vpb.cc
+++ b/channels/chan_vpb.cc
@@ -2471,7 +2471,6 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st
ast_channel_exten_set(tmp, "s");
if (!ast_strlen_zero(me->language))
ast_channel_language_set(tmp, me->language);
-
ast_channel_unlock(tmp);
me->owner = tmp;
diff --git a/channels/sig_analog.c b/channels/sig_analog.c
index bbf7a3c8c..51d3f1495 100644
--- a/channels/sig_analog.c
+++ b/channels/sig_analog.c
@@ -2120,6 +2120,7 @@ static void *__analog_ss_thread(void *data)
getforward = 0;
} else {
res = analog_play_tone(p, idx, -1);
+ ast_channel_lock(chan);
ast_channel_exten_set(chan, exten);
if (!ast_strlen_zero(p->cid_num)) {
if (!p->hidecallerid) {
@@ -2134,6 +2135,7 @@ static void *__analog_ss_thread(void *data)
}
}
ast_setstate(chan, AST_STATE_RING);
+ ast_channel_unlock(chan);
analog_set_echocanceller(p, 1);
res = ast_pbx_run(chan);
if (res) {
@@ -2615,8 +2617,10 @@ static void *__analog_ss_thread(void *data)
analog_handle_notify_message(chan, p, flags, -1);
+ ast_channel_lock(chan);
ast_setstate(chan, AST_STATE_RING);
ast_channel_rings_set(chan, 1);
+ ast_channel_unlock(chan);
analog_set_ringtimeout(p, p->ringt_base);
res = ast_pbx_run(chan);
if (res) {
diff --git a/channels/sig_pri.c b/channels/sig_pri.c
index 5def34c23..48c8c33d7 100644
--- a/channels/sig_pri.c
+++ b/channels/sig_pri.c
@@ -2160,7 +2160,9 @@ static void *pri_ss_thread(void *data)
#endif /* defined(ISSUE_16789) */
sig_pri_set_echocanceller(p, 1);
+ ast_channel_lock(chan);
ast_setstate(chan, AST_STATE_RING);
+ ast_channel_unlock(chan);
res = ast_pbx_run(chan);
if (res) {
ast_log(LOG_WARNING, "PBX exited non-zero!\n");