diff options
author | RĂ©mi Verschelde <remi@verschelde.fr> | 2022-04-11 17:55:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-11 17:55:35 +0200 |
commit | f62f36cd91ce6f572317394137cb12c5fbf6c234 (patch) | |
tree | dee06c527bdcbb6f8e7353f874be98494fee7aa6 | |
parent | bbd8651d87f4769a62369d6e5b17a28dba82acb9 (diff) | |
parent | 4f3769fd75eb4f3b123c9f4d47cd5ab470faa131 (diff) |
Merge pull request #53573 from Klowner/53568-safelist-leak-fix
-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 } }; |