mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-12 21:10:42 +00:00
Ensure parent refs are deleted before force-deleting resource records
* This most commonly happens with shaders and programs. A program record takes a reference on shader records when they are attached and linked, then a shader can be orphaned with only that reference remaining if the user code detaches and deletes it. * Previously we would go through, force-delete the shader, then when we force-delete the program things would explode since it tries to decrement the refcount on the shader and it becomes -1. So now we make all records remove their parents (which might delete their parents), before we force delete them.
This commit is contained in:
@@ -42,6 +42,40 @@ class GLResourceManager : public ResourceManager<GLResource, GLResourceRecord>
|
||||
|
||||
void Shutdown()
|
||||
{
|
||||
// there's a bit of a dependency issue here. We're essentially forcibly deleting/garbage collecting
|
||||
// all the resource records. In some cases, we might have a parent->child type relationship where
|
||||
// the only reference on the parent is from the child. If we delete the parent before the child,
|
||||
// when the child destructs and tries to delete the parent things will go badly.
|
||||
// We want to avoid keeping a reference ourselves on all records since that would cause difficulties
|
||||
// during normal lifetime, so instead we just ask all records to release their references on parents
|
||||
// before deleting them.
|
||||
|
||||
// special care is taken since the act of freeing parents will by design potentially modify the
|
||||
// container. Since this is shutdown, we take the simple & naive approach of simply restarting the
|
||||
// loop whenever we detect the size changing. FreeParents() is a safe operation to perform on records
|
||||
// that have already freed their parents.
|
||||
{
|
||||
auto it = m_GLResourceRecords.begin();
|
||||
|
||||
for(size_t i=0; it != m_GLResourceRecords.end();)
|
||||
{
|
||||
size_t prevSize = m_GLResourceRecords.size();
|
||||
it->second->FreeParents(this);
|
||||
|
||||
// collection modified, restart loop
|
||||
if(prevSize != m_GLResourceRecords.size())
|
||||
{
|
||||
i = 0;
|
||||
it = m_GLResourceRecords.begin();
|
||||
continue;
|
||||
}
|
||||
|
||||
// collection not modified, continue
|
||||
i++;
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
while(!m_GLResourceRecords.empty())
|
||||
{
|
||||
auto it = m_GLResourceRecords.begin();
|
||||
|
||||
Reference in New Issue
Block a user