mirror of
https://github.com/love2d/love.git
synced 2026-08-12 16:40:57 +02:00
Fixed shutdown crash in ~Math.
The 'registry' global in Module.cpp appears to be destroyed before the last module is destroyed, specifically the math module. This is bad, because ~Module tries to look for itself in 'registry' after it's gone. This causes a nasty debug assert in VS2012, and a shutdown crash in release builds. Fixed by dynamically allocating/releasing the registry.
This commit is contained in:
+39
-10
@@ -29,7 +29,30 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
std::map<std::string, love::Module*> registry;
|
||||
typedef std::map<std::string, love::Module*> ModuleRegistry;
|
||||
|
||||
// The registry must be dynamically managed, because some modules
|
||||
// (the math module) are static globals that are not guaranteed to
|
||||
// be destroyed before other static globals.
|
||||
ModuleRegistry *registry = nullptr;
|
||||
|
||||
ModuleRegistry ®istryInstance()
|
||||
{
|
||||
if (!registry)
|
||||
registry = new ModuleRegistry;
|
||||
|
||||
return *registry;
|
||||
}
|
||||
|
||||
void freeEmptyRegistry()
|
||||
{
|
||||
if (registry && registry->empty())
|
||||
{
|
||||
delete registry;
|
||||
registry = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace love
|
||||
@@ -37,10 +60,10 @@ namespace love
|
||||
|
||||
Module::~Module()
|
||||
{
|
||||
std::map<std::string, Module*>::iterator it;
|
||||
ModuleRegistry ®istry = registryInstance();
|
||||
|
||||
// We can't use the overridden Module::getName() in this destructor.
|
||||
for (it = registry.begin(); it != registry.end(); ++it)
|
||||
for (auto it = registry.begin(); it != registry.end(); ++it)
|
||||
{
|
||||
if (it->second == this)
|
||||
{
|
||||
@@ -48,16 +71,20 @@ Module::~Module()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
freeEmptyRegistry();
|
||||
}
|
||||
|
||||
void Module::registerInstance(Module *instance)
|
||||
{
|
||||
if (instance == NULL)
|
||||
if (instance == nullptr)
|
||||
throw Exception("Module instance is NULL");
|
||||
|
||||
std::string name(instance->getName());
|
||||
|
||||
std::map<std::string, Module*>::iterator it = registry.find(name);
|
||||
ModuleRegistry ®istry = registryInstance();
|
||||
|
||||
auto it = registry.find(name);
|
||||
|
||||
if (it != registry.end())
|
||||
{
|
||||
@@ -71,25 +98,27 @@ void Module::registerInstance(Module *instance)
|
||||
|
||||
Module *Module::getInstance(const std::string &name)
|
||||
{
|
||||
std::map<std::string, Module*>::const_iterator it = registry.find(name);
|
||||
ModuleRegistry ®istry = registryInstance();
|
||||
|
||||
auto it = registry.find(name);
|
||||
|
||||
if (registry.end() == it)
|
||||
return NULL;
|
||||
return nullptr;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
Module *Module::findInstance(const std::string &name)
|
||||
{
|
||||
std::map<std::string, Module*>::const_iterator it;
|
||||
ModuleRegistry ®istry = registryInstance();
|
||||
|
||||
for (it = registry.begin(); it != registry.end(); ++it)
|
||||
for (auto it = registry.begin(); it != registry.end(); ++it)
|
||||
{
|
||||
if (it->first.find(name) == 0)
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // love
|
||||
|
||||
Reference in New Issue
Block a user