diff options
author | Mark Riedesel <mark@klowner.com> | 2021-10-08 11:25:34 -0400 |
---|---|---|
committer | Mark Riedesel <mark@klowner.com> | 2022-04-08 09:50:49 -0400 |
commit | 4f3769fd75eb4f3b123c9f4d47cd5ab470faa131 (patch) | |
tree | d0c085dc240d8ae9d8113d12f24a5511056b8aa3 /core/templates | |
parent | ac591d9904e4e5cf7841b3e79caabf558d37db0e (diff) |
add SafeList destructor which calls maybe_cleanup() to prevent mem leak
Diffstat (limited to 'core/templates')
-rw-r--r-- | core/templates/safe_list.h | 30 |
1 files changed, 26 insertions, 4 deletions
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<SafeListNode, A>(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<SafeListNode, A>(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 } }; |