Fix a crash on quit if a deprecated function was used.

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2017-10-21 22:37:51 -03:00
parent 90cb3870e7
commit 4f8e04d391
+21 -10
View File
@@ -28,8 +28,8 @@
namespace love namespace love
{ {
static std::map<std::string, DeprecationInfo> deprecated; static std::map<std::string, DeprecationInfo> *deprecated = nullptr;
static std::vector<const DeprecationInfo *> deprecatedList; static std::vector<const DeprecationInfo *> *deprecatedList = nullptr;
static std::atomic<int> initCount; static std::atomic<int> initCount;
@@ -39,17 +39,28 @@ static bool outputEnabled = false;
void initDeprecation() void initDeprecation()
{ {
if (initCount.fetch_add(1) == 0) if (initCount.fetch_add(1) == 0)
{
mutex = thread::newMutex(); mutex = thread::newMutex();
// These are heap-allocated because we want to clear them on deinit,
// and deinit may be called when the program is shutting down in the
// middle of static variable cleanup (eg in the Math module destructor).
// Calling std::map::clear() in that case was causing segfaults.
deprecated = new std::map<std::string, DeprecationInfo>();
deprecatedList = new std::vector<const DeprecationInfo *>();
}
} }
void deinitDeprecation() void deinitDeprecation()
{ {
if (initCount.fetch_sub(1) == 1) if (initCount.fetch_sub(1) == 1)
{ {
deprecatedList.clear(); delete deprecated;
deprecated.clear(); delete deprecatedList;
delete mutex; delete mutex;
deprecated = nullptr;
deprecatedList = nullptr;
mutex = nullptr; mutex = nullptr;
} }
} }
@@ -115,7 +126,7 @@ std::string getDeprecationNotice(const DeprecationInfo &info, bool usewhere)
} }
GetDeprecated::GetDeprecated() GetDeprecated::GetDeprecated()
: all(deprecatedList) : all(*deprecatedList)
{ {
if (mutex != nullptr) if (mutex != nullptr)
mutex->lock(); mutex->lock();
@@ -138,9 +149,9 @@ MarkDeprecated::MarkDeprecated(const char *name, APIType api, DeprecationType ty
if (mutex != nullptr) if (mutex != nullptr)
mutex->lock(); mutex->lock();
auto it = deprecated.find(name); auto it = deprecated->find(name);
if (it != deprecated.end()) if (it != deprecated->end())
{ {
it->second.uses++; it->second.uses++;
info = &it->second; info = &it->second;
@@ -157,10 +168,10 @@ MarkDeprecated::MarkDeprecated(const char *name, APIType api, DeprecationType ty
if (replacement != nullptr) if (replacement != nullptr)
newinfo.replacement = replacement; newinfo.replacement = replacement;
auto inserted = deprecated.insert(std::make_pair(newinfo.name, newinfo)); auto inserted = deprecated->insert(std::make_pair(newinfo.name, newinfo));
info = &inserted.first->second; info = &inserted.first->second;
deprecatedList.push_back(info); deprecatedList->push_back(info);
} }
} }