diff --git a/channels/chan_local.c b/channels/chan_local.c index eca253831f..f7d8f10393 100644 --- a/channels/chan_local.c +++ b/channels/chan_local.c @@ -1112,6 +1112,9 @@ static struct ast_channel *local_new(struct local_pvt *p, int state, const char ama = p->owner->amaflags; else ama = 0; + + /* 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, tmp->linkedid, ama, "Local/%s@%s-%04x;2", p->exten, p->context, randnum))) { if (tmp) { diff --git a/main/cel.c b/main/cel.c index fbcaa104b3..023fd571a9 100644 --- a/main/cel.c +++ b/main/cel.c @@ -377,10 +377,9 @@ void ast_cel_check_retire_linkedid(struct ast_channel *chan) return; } - /* We have a ref for each channel with this linkedid, the link and the above find, so if after - * unreffing for the channel we have a ref of 2, we're done. Unlink and report. */ - ao2_ref(lid, -1); - if (ao2_ref(lid, 0) == 2) { + /* We have a ref for each channel with this linkedid, the link and the above find, so if + * before unreffing the channel we have a refcount of 3, we're done. Unlink and report. */ + if (ao2_ref(lid, -1) == 3) { ao2_unlink(linkedids, lid); ast_cel_report_event(chan, AST_CEL_LINKEDID_END, NULL, NULL, NULL); } @@ -488,7 +487,11 @@ int ast_cel_report_event(struct ast_channel *chan, enum ast_cel_event_type event return -1; } strcpy(lid, chan->linkedid); - ao2_link(linkedids, lid); + if (!ao2_link(linkedids, lid)) { + ao2_ref(lid, -1); + ast_mutex_unlock(&reload_lock); + return -1; + } /* Leave both the link and the alloc refs to show a count of 1 + the link */ } /* If we've found, go ahead and keep the ref to increment count of how many channels