浏览代码

Workaround for crash due to static destruction order

Ivan Savenko 6 月之前
父节点
当前提交
8771ecdf57
共有 2 个文件被更改,包括 19 次插入1 次删除
  1. 14 1
      lib/CConfigHandler.cpp
  2. 5 0
      lib/CConfigHandler.h

+ 14 - 1
lib/CConfigHandler.cpp

@@ -55,6 +55,13 @@ SettingsStorage::SettingsStorage():
 {
 }
 
+SettingsStorage::~SettingsStorage()
+{
+	// hack for possible crash due to static destruction order (setting storage can be destroyed before all listeners have died)
+	for(SettingsListener * listener : listeners)
+		listener->terminate();
+}
+
 void SettingsStorage::init(const std::string & dataFilename, const std::string & schema)
 {
 	this->dataFilename = dataFilename;
@@ -132,9 +139,15 @@ SettingsListener::SettingsListener(const SettingsListener &sl):
 	parent.listeners.insert(this);
 }
 
+void SettingsListener::terminate()
+{
+	wasTerminated = true;
+}
+
 SettingsListener::~SettingsListener()
 {
-	parent.listeners.erase(this);
+	if (!wasTerminated)
+		parent.listeners.erase(this);
 }
 
 void SettingsListener::nodeInvalidated(const std::vector<std::string> &changedPath)

+ 5 - 0
lib/CConfigHandler.h

@@ -48,6 +48,7 @@ class DLL_LINKAGE SettingsStorage
 public:
 	// Initialize config structure
 	SettingsStorage();
+	~SettingsStorage();
 	void init(const std::string & dataFilename, const std::string & schema);
 	
 	// Get write access to config node at path
@@ -73,11 +74,15 @@ class DLL_LINKAGE SettingsListener
 	// Callback
 	std::function<void(const JsonNode&)> callback;
 
+	// hack for crash due to static destruction order
+	bool wasTerminated = false;
+
 	SettingsListener(SettingsStorage & _parent, std::vector<std::string> _path);
 
 	// Executes callback if changedpath begins with path
 	void nodeInvalidated(const std::vector<std::string> & changedPath);
 
+	void terminate();
 public:
 	SettingsListener(const SettingsListener &sl);
 	~SettingsListener();