Fix T40199: bge.logic.LibFree() could cause crashes by leaving dangling pointers in the rasterizer.

This commit is contained in:
Mitchell Stokes 2014-05-14 19:11:08 -07:00
parent 064ef3f00f
commit ff2ec05662
2 changed files with 36 additions and 1 deletions

@ -1382,10 +1382,42 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
}
vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator meshit;
RAS_BucketManager::BucketList::iterator bit;
list<RAS_MeshSlot>::iterator msit;
RAS_BucketManager::BucketList buckets;
size = m_meshobjects.size();
for (i=0, meshit=m_meshobjects.begin(); i<size; ) {
RAS_MeshObject *me= (*meshit).second;
if (IS_TAGGED(me->GetMesh())) {
// Before deleting the mesh object, make sure the rasterizer is
// no longer referencing it.
buckets = meshit->first->GetBucketManager()->GetSolidBuckets();
for (bit=buckets.begin(); bit!=buckets.end(); bit++) {
msit = (*bit)->msBegin();
while (msit != (*bit)->msEnd()) {
if (msit->m_mesh == meshit->second)
(*bit)->RemoveMesh(&(*msit++));
else
msit++;
}
}
// And now the alpha buckets
buckets = meshit->first->GetBucketManager()->GetAlphaBuckets();
for (bit=buckets.begin(); bit!=buckets.end(); bit++) {
msit = (*bit)->msBegin();
while (msit != (*bit)->msEnd()) {
if (msit->m_mesh == meshit->second)
(*bit)->RemoveMesh(&(*msit++));
else
msit++;
}
}
// Now it should be safe to delete
delete (*meshit).second;
*meshit = m_meshobjects.back();
m_meshobjects.pop_back();
@ -1536,7 +1568,8 @@ RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene,
}
}
}
m_currentScene = kx_scene; // This needs to be set in case we LibLoaded earlier
RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this, false);
kx_scene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
m_map_mesh_to_gamemesh.clear(); /* This is at runtime so no need to keep this, BL_ConvertMesh adds */

@ -39,7 +39,9 @@
class RAS_BucketManager
{
public:
typedef std::vector<class RAS_MaterialBucket*> BucketList;
private:
BucketList m_SolidBuckets;
BucketList m_AlphaBuckets;