From 6d56c87d848517bc3d941628bb40433656b759f1 Mon Sep 17 00:00:00 2001 From: skyjake Date: Sun, 26 Aug 2012 18:06:11 +0300 Subject: [PATCH] libdeng|Str|Debug: Verify that AutoStr instances are not manually deleted AutoStr instances must only be deleted by the garbage recycler. Added an assertion to verify that Str_Delete() is not called on AutoStrs. --- doomsday/libdeng/src/garbage.cpp | 11 +++++++++++ doomsday/libdeng/src/str.c | 23 ++++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/doomsday/libdeng/src/garbage.cpp b/doomsday/libdeng/src/garbage.cpp index 41bcd5430b..d751633932 100644 --- a/doomsday/libdeng/src/garbage.cpp +++ b/doomsday/libdeng/src/garbage.cpp @@ -32,6 +32,10 @@ struct Garbage { typedef std::map Allocs; // O(log n) search Allocs allocs; + bool beingRecycled; + + Garbage() : beingRecycled(false) + {} ~Garbage() { @@ -40,6 +44,8 @@ struct Garbage bool contains(const void* ptr) const { + if(beingRecycled) return false; + Allocs::const_iterator i = allocs.find(const_cast(ptr)); return i != allocs.end(); } @@ -48,6 +54,8 @@ struct Garbage { if(allocs.empty()) return; + beingRecycled = true; + LOG_DEBUG("Recycling %i allocations/instances.") << allocs.size(); for(Allocs::iterator i = allocs.begin(); i != allocs.end(); ++i) @@ -56,6 +64,8 @@ struct Garbage i->second(i->first); } allocs.clear(); + + beingRecycled = false; } }; @@ -129,6 +139,7 @@ void Garbage_TrashInstance(void* ptr, GarbageDestructor destructor) boolean Garbage_IsTrashed(const void* ptr) { + if(!garbages) return false; Garbage* g = garbageForThread(Sys_CurrentThreadId()); return g->contains(ptr); } diff --git a/doomsday/libdeng/src/str.c b/doomsday/libdeng/src/str.c index 74efd25aa3..58b81547f0 100644 --- a/doomsday/libdeng/src/str.c +++ b/doomsday/libdeng/src/str.c @@ -191,7 +191,7 @@ ddstring_t* Str_NewFromReader(Reader* reader) return str; } -void Str_Delete(ddstring_t* str) +static void deleteString(Str* str) { DENG_ASSERT(str); if(!str) return; @@ -200,6 +200,18 @@ void Str_Delete(ddstring_t* str) M_Free(str); } +void Str_Delete(Str* str) +{ + DENG_ASSERT(!Garbage_IsTrashed(str)); + + if(Garbage_IsTrashed(str)) + { + LegacyCore_FatalError("Str_Delete: Trying to manually delete an AutoStr!"); + } + + deleteString(str); +} + ddstring_t* Str_Clear(ddstring_t* str) { return Str_Set(str, ""); @@ -807,10 +819,15 @@ AutoStr* AutoStr_NewStd(void) return AutoStr_FromStr(Str_NewStd()); } -AutoStr* AutoStr_FromStr(ddstring_t* str) +void AutoStr_Delete(AutoStr* as) +{ + deleteString(as); +} + +AutoStr* AutoStr_FromStr(Str* str) { DENG_ASSERT(str); - Garbage_TrashInstance(str, (GarbageDestructor) Str_Delete); + Garbage_TrashInstance(str, (GarbageDestructor) AutoStr_Delete); return str; }