summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2018-02-09 12:06:08 -0600
committerRichard Mudgett <rmudgett@digium.com>2018-02-09 14:26:46 -0600
commitb2fcb30d388ae7ec0c51a9719f54de006ad2478f (patch)
treefec5dd9779f9ddc6d6add36f3758c27cd8effdb2 /main
parente132f22a2ef89ca7b7fa7e9a77d4e1aad64bf203 (diff)
cdr.c: Fix runtime leak of CDR records.
Need to remove all CDR's listed by a CDR object from the active_cdrs_all container including the root/master record. ASTERISK-27656 Change-Id: I48b4970663fea98baa262593d2204ef304aaf80e
Diffstat (limited to 'main')
-rw-r--r--main/cdr.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/main/cdr.c b/main/cdr.c
index 8acae607f..4acadf975 100644
--- a/main/cdr.c
+++ b/main/cdr.c
@@ -371,7 +371,7 @@ static ast_cond_t cdr_pending_cond;
/*! \brief A container of the active master CDRs indexed by Party A channel uniqueid */
static struct ao2_container *active_cdrs_master;
-/*! \brief A container of all active CDRs indexed by Party B channel name */
+/*! \brief A container of all active CDRs with a Party B indexed by Party B channel name */
static struct ao2_container *active_cdrs_all;
/*! \brief Message router for stasis messages regarding channel state */
@@ -971,13 +971,21 @@ static void cdr_all_unlink(struct cdr_object *cdr)
ast_assert(cdr->is_root);
+ /* Hold a ref to the root CDR to ensure the list members don't go away on us. */
+ ao2_ref(cdr, +1);
ao2_lock(active_cdrs_all);
- for (cur = cdr->next; cur; cur = next) {
+ for (cur = cdr; cur; cur = next) {
next = cur->next;
ao2_unlink_flags(active_cdrs_all, cur, OBJ_NOLOCK);
+ /*
+ * It is safe to still use cur after unlinking because the
+ * root CDR holds a ref to all the CDRs in the list and we
+ * have a ref to the root CDR.
+ */
ast_string_field_set(cur, party_b_name, "");
}
ao2_unlock(active_cdrs_all);
+ ao2_ref(cdr, -1);
}
/*!