From 4f3769fd75eb4f3b123c9f4d47cd5ab470faa131 Mon Sep 17 00:00:00 2001 From: Mark Riedesel Date: Fri, 8 Oct 2021 11:25:34 -0400 Subject: add SafeList destructor which calls maybe_cleanup() to prevent mem leak --- core/templates/safe_list.h | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'core/templates') diff --git a/core/templates/safe_list.h b/core/templates/safe_list.h index ae31525dd0..e850f3bd5e 100644 --- a/core/templates/safe_list.h +++ b/core/templates/safe_list.h @@ -203,7 +203,7 @@ public: } // Calling this will cause zero to many deallocations. - void maybe_cleanup() { + bool maybe_cleanup() { SafeListNode *cursor = nullptr; SafeListNode *new_graveyard_head = nullptr; do { @@ -212,7 +212,7 @@ public: if (active_iterator_count.load() != 0) { // It's not safe to clean up with an active iterator, because that iterator // could be pointing to an element that we want to delete. - return; + return false; } // Any iterator created after this point will never point to a deleted node. // Swap it out with the current graveyard head. @@ -225,6 +225,17 @@ public: tmp->deletion_fn(tmp->val); memdelete_allocator(tmp); } + return true; + } + + ~SafeList() { +#ifdef DEBUG_ENABLED + if (!maybe_cleanup()) { + ERR_PRINT("There are still iterators around when destructing a SafeList. Memory will be leaked. This is a bug."); + } +#else + maybe_cleanup(); +#endif } }; @@ -353,11 +364,11 @@ public: } // Calling this will cause zero to many deallocations. - void maybe_cleanup() { + bool maybe_cleanup() { SafeListNode *cursor = graveyard_head; if (active_iterator_count != 0) { // It's not safe to clean up with an active iterator, because that iterator could be pointing to an element that we want to delete. - return; + return false; } graveyard_head = nullptr; // Our graveyard list is now unreachable by any active iterators, detached from the main graveyard head and ready for deletion. @@ -367,6 +378,17 @@ public: tmp->deletion_fn(tmp->val); memdelete_allocator(tmp); } + return true; + } + + ~SafeList() { +#ifdef DEBUG_ENABLED + if (!maybe_cleanup()) { + ERR_PRINT("There are still iterators around when destructing a SafeList. Memory will be leaked. This is a bug."); + } +#else + maybe_cleanup(); +#endif } }; -- cgit v1.2.3