summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorTerry Wilson <twilson@digium.com>2012-05-02 17:43:16 +0000
committerTerry Wilson <twilson@digium.com>2012-05-02 17:43:16 +0000
commit07309e586cd26bc533b2ad1382fa35ab80fdc8fd (patch)
treee1b8cf833732dea3f57a4ecc7b594cda2b032aaf /channels
parentff06b448b87e178dfb949eb8bc4a3273c579329b (diff)
Multiple revisions 365006,365068
........ r365006 | twilson | 2012-05-02 10:49:03 -0500 (Wed, 02 May 2012) | 12 lines Fix a CEL LINKEDID_END race and local channel linkedids This patch has the ;2 channel inherit the linkedid of the ;1 channel and fixes the race condition by no longer scanning the channel list for "other" channels with the same linkedid. Instead, cel.c has an ao2 container of linkedid strings and uses the refcount of the string as a counter of how many channels with the linkedid exist. Not only does this eliminate the race condition, but it also allows us to look up the linkedid by the hashed key instead of traversing the entire channel list. Review: https://reviewboard.asterisk.org/r/1895/ ........ r365068 | twilson | 2012-05-02 12:02:39 -0500 (Wed, 02 May 2012) | 11 lines Don't leak a ref if out of memory and can't link the linkedid If the ao2_link fails, we are most likely out of memory and bad things are going to happen. Before those bad things happen, make sure to clean up the linkedid references. This patch also adds a comment explaining why linkedid can't be passed to both local channel allocations and combines two ao2_ref calls into 1. Review: https://reviewboard.asterisk.org/r/1895/ ........ Merged revisions 365006,365068 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 365083 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@365084 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_local.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/channels/chan_local.c b/channels/chan_local.c
index 1a8ea17ec..f7522fbba 100644
--- a/channels/chan_local.c
+++ b/channels/chan_local.c
@@ -1128,8 +1128,11 @@ static struct ast_channel *local_new(struct local_pvt *p, int state, const char
ama = ast_channel_amaflags(p->owner);
else
ama = 0;
- if (!(tmp = ast_channel_alloc(1, state, 0, 0, t, p->exten, p->context, linkedid, ama, "Local/%s@%s-%04x;1", p->exten, p->context, randnum))
- || !(tmp2 = ast_channel_alloc(1, AST_STATE_RING, 0, 0, t, p->exten, p->context, linkedid, ama, "Local/%s@%s-%04x;2", p->exten, p->context, randnum))) {
+
+ /* Make sure that the ;2 channel gets the same linkedid as ;1. You can't pass linkedid to both
+ * allocations since if linkedid isn't set, then each channel will generate its own linkedid. */
+ if (!(tmp = ast_channel_alloc(1, state, 0, 0, t, p->exten, p->context, linkedid, ama, "Local/%s@%s-%04x;1", p->exten, p->context, randnum))
+ || !(tmp2 = ast_channel_alloc(1, AST_STATE_RING, 0, 0, t, p->exten, p->context, ast_channel_linkedid(tmp), ama, "Local/%s@%s-%04x;2", p->exten, p->context, randnum))) {
if (tmp) {
tmp = ast_channel_release(tmp);
}