Skip to content

Commit

Permalink
libdeng|Str|Debug: Verify that AutoStr instances are not manually del…
Browse files Browse the repository at this point in the history
…eted

AutoStr instances must only be deleted by the garbage recycler. Added
an assertion to verify that Str_Delete() is not called on AutoStrs.
  • Loading branch information
skyjake committed Aug 26, 2012
1 parent bbd42ce commit 6d56c87
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
11 changes: 11 additions & 0 deletions doomsday/libdeng/src/garbage.cpp
Expand Up @@ -32,6 +32,10 @@ struct Garbage
{
typedef std::map<void*, GarbageDestructor> Allocs; // O(log n) search
Allocs allocs;
bool beingRecycled;

Garbage() : beingRecycled(false)
{}

~Garbage()
{
Expand All @@ -40,6 +44,8 @@ struct Garbage

bool contains(const void* ptr) const
{
if(beingRecycled) return false;

Allocs::const_iterator i = allocs.find(const_cast<void*>(ptr));
return i != allocs.end();
}
Expand All @@ -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)
Expand All @@ -56,6 +64,8 @@ struct Garbage
i->second(i->first);
}
allocs.clear();

beingRecycled = false;
}
};

Expand Down Expand Up @@ -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);
}
Expand Down
23 changes: 20 additions & 3 deletions doomsday/libdeng/src/str.c
Expand Up @@ -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;
Expand All @@ -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, "");
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit 6d56c87

Please sign in to comment.