diff options
author | Jenkins2 <jenkins2@gerrit.asterisk.org> | 2018-02-12 16:03:46 -0600 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2018-02-12 16:03:46 -0600 |
commit | 0461286123e3ab201374f8b8a2435ed6006b7a5a (patch) | |
tree | a1a515d40e8a370da6487204c7ecbdd0d7c51eba /main | |
parent | c86ed5a69d4837f9d9cf6c2463adb987d6225bed (diff) | |
parent | b2fcb30d388ae7ec0c51a9719f54de006ad2478f (diff) |
Merge "cdr.c: Fix runtime leak of CDR records."
Diffstat (limited to 'main')
-rw-r--r-- | main/cdr.c | 12 |
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); } /*! |