diff --git a/GCPointer/src/GCPointer.h b/GCPointer/src/GCPointer.h index 4240c98..a6deb7f 100644 --- a/GCPointer/src/GCPointer.h +++ b/GCPointer/src/GCPointer.h @@ -32,6 +32,7 @@ namespace gc Deleter& deleter; uint refCount; bool marked; + bool deleted; void deletePointee() { @@ -186,8 +187,11 @@ namespace gc { if (backing && --backing->refCount == 0) { - delete (T*) backing->to; - delete backing; + if (!gc_pool::instance().isCollecting) + { + delete (T*) backing->to; + delete backing; + } } backing = nullptr; diff --git a/GCPointer/src/GCPool.h b/GCPointer/src/GCPool.h index 8a74411..168e98d 100644 --- a/GCPointer/src/GCPool.h +++ b/GCPointer/src/GCPool.h @@ -2,6 +2,7 @@ #include "GCPointer.h" #include +#include namespace gc { @@ -23,11 +24,14 @@ namespace gc friend size_t live_pointer_count(); using OwnerPointerMap = std::multimap; + using BackingSet = std::set; using MapIt = typename OwnerPointerMap::iterator; using Range = std::pair; OwnerPointerMap owned; + BackingSet backings; MapIt lastInsertion; + bool isCollecting = false; void reset() { @@ -37,6 +41,8 @@ namespace gc void add(gc_ptr_base& ptr) { lastInsertion = owned.insert({ ptr.owner, &ptr }); + if (ptr.backing) + backings.insert(ptr.backing); } void remove(gc_ptr_base& ptr) @@ -74,35 +80,20 @@ namespace gc void deleteUnmarked() { - for (auto it = owned.begin(); it != owned.end(); ) + isCollecting = true; // TODO: Lock? + + for (auto it : backings) { - gc_ptr_base& ptr = *it->second; - if (ptr.backing && !ptr.backing->marked) - { - auto* backing = ptr.backing; - nullifyPointersTo(backing->to); - backing->deletePointee(); - delete backing; - - // Iterator now invalid, start again - it = owned.begin(); - } - else - ++it; + gc_ptr_base::Backing& backing = *it; + if (!backing.marked) + backing.deletePointee(); } + + //TODO: Remove invalid backings + + isCollecting = false; } - void nullifyPointersTo(OwnerType* pointee) - { - for (auto entry : owned) - { - gc_ptr_base& p = *entry.second; - if (p.backing && (p.backing->to == pointee)) - { - p.backing = nullptr; - } - } - } void unmarkAll() { diff --git a/Tests/GCPointerTest.cpp b/Tests/GCPointerTest.cpp index 8ffd476..e0ec8da 100644 --- a/Tests/GCPointerTest.cpp +++ b/Tests/GCPointerTest.cpp @@ -276,4 +276,4 @@ TEST_F(GCPointerTest, ownersNeedNotBeGCObjects) p->selfReference = p; } collectGarbage(); -} +} \ No newline at end of file