Fix memory leaks

* Fix recursive reference memory leak in UIWidget
* Make Event/ScheduledEvent memory-leak safe
* Fix exit crashs by freeing graphics resources before destroying GL context
* Add many asserts to avoid any leak regression
This commit is contained in:
Eduardo Bart
2012-06-18 05:13:52 -03:00
parent f650b0e5bb
commit 1c7bbaea89
42 changed files with 326 additions and 81 deletions

View File

@@ -57,6 +57,11 @@ bool ConfigManager::save()
return m_confsDoc->save(m_fileName);
}
void ConfigManager::clear()
{
m_confsDoc->clear();
}
void ConfigManager::set(const std::string& key, const std::string& value)
{
if(key == "") {

View File

@@ -32,6 +32,7 @@ public:
ConfigManager();
bool load(const std::string& file);
bool save();
void clear();
void set(const std::string& key, const std::string& value);
void setList(const std::string& key, const std::vector<std::string>& list);

View File

@@ -32,8 +32,12 @@ void EventDispatcher::flush()
while(!m_eventList.empty())
poll();
while(!m_scheduledEventList.empty())
while(!m_scheduledEventList.empty()) {
ScheduledEventPtr scheduledEvent = m_scheduledEventList.top();
scheduledEvent->cancel();
m_scheduledEventList.pop();
}
m_disabled = true;
}
void EventDispatcher::poll()
@@ -77,6 +81,9 @@ void EventDispatcher::poll()
ScheduledEventPtr EventDispatcher::scheduleEvent(const std::function<void()>& callback, int delay)
{
if(m_disabled)
return ScheduledEventPtr(new ScheduledEvent(nullptr, delay, 1));
assert(delay >= 0);
ScheduledEventPtr scheduledEvent(new ScheduledEvent(callback, delay, 1));
m_scheduledEventList.push(scheduledEvent);
@@ -85,6 +92,9 @@ ScheduledEventPtr EventDispatcher::scheduleEvent(const std::function<void()>& ca
ScheduledEventPtr EventDispatcher::cycleEvent(const std::function<void()>& callback, int delay)
{
if(m_disabled)
return ScheduledEventPtr(new ScheduledEvent(nullptr, delay, 0));
assert(delay > 0);
ScheduledEventPtr scheduledEvent(new ScheduledEvent(callback, delay, 0));
m_scheduledEventList.push(scheduledEvent);
@@ -93,6 +103,9 @@ ScheduledEventPtr EventDispatcher::cycleEvent(const std::function<void()>& callb
EventPtr EventDispatcher::addEvent(const std::function<void()>& callback, bool pushFront)
{
if(m_disabled)
return EventPtr(new Event(nullptr));
EventPtr event(new Event(callback));
// front pushing is a way to execute an event before others
if(pushFront) {

View File

@@ -31,14 +31,24 @@ class Event : public LuaObject
{
public:
Event(const std::function<void()>& callback) : m_callback(callback), m_canceled(false), m_executed(false) { }
virtual ~Event() {
// assure that we lost callback refs
assert(m_callback == nullptr);
}
virtual void execute() {
if(!m_canceled && !m_executed && m_callback) {
m_callback();
m_executed = true;
}
// reset callback to free object refs
m_callback = nullptr;
}
void cancel() {
m_canceled = true;
m_callback = nullptr;
}
void cancel() { m_canceled = true; }
bool isCanceled() { return m_canceled; }
bool isExecuted() { return m_executed; }
@@ -63,17 +73,21 @@ public:
if(!m_canceled && m_callback && (m_maxCycles == 0 || m_cyclesExecuted < m_maxCycles)) {
m_callback();
m_executed = true;
// callback may be used in the next cycle
} else {
// reset callback to free object refs
m_callback = nullptr;
}
m_cyclesExecuted++;
}
bool nextCycle() {
if(m_canceled)
return false;
if(m_maxCycles == 0 || m_cyclesExecuted < m_maxCycles) {
if(m_callback && !m_canceled && (m_maxCycles == 0 || m_cyclesExecuted < m_maxCycles)) {
m_ticks += m_delay;
return true;
}
// reset callback to free object refs
m_callback = nullptr;
return false;
}
@@ -109,6 +123,7 @@ public:
private:
std::list<EventPtr> m_eventList;
int m_pollEventsSize;
Boolean<false> m_disabled;
std::priority_queue<ScheduledEventPtr, std::vector<ScheduledEventPtr>, lessScheduledEvent> m_scheduledEventList;
};

View File

@@ -28,6 +28,12 @@
ModuleManager g_modules;
void ModuleManager::clear()
{
m_modules.clear();
m_autoLoadModules.clear();
}
void ModuleManager::discoverModules()
{
// remove modules that are not loaded

View File

@@ -28,6 +28,8 @@
class ModuleManager
{
public:
void clear();
void discoverModulesPath();
void discoverModules();
void autoLoadModules(int maxPriority);