mirror of
https://invent.kde.org/system/dolphin
synced 2024-07-04 17:30:55 +00:00
versioncontrol: Prevent a use-after-free in UpdateItemStatesThread
UpdateItemStatesThread kept a pointer reference to m_plugin whose lifetime was tied to VersionControlObserver parents. On application shutdown it could happen the thread is still running when the Observer is destroyed. Make the plugin pointer a weak reference, allowing to stop the thread when the plugin is gone. BUG: 477425
This commit is contained in:
parent
5795d57dcb
commit
d270700c0e
|
@ -26,22 +26,26 @@ UpdateItemStatesThread::~UpdateItemStatesThread()
|
||||||
void UpdateItemStatesThread::run()
|
void UpdateItemStatesThread::run()
|
||||||
{
|
{
|
||||||
Q_ASSERT(!m_itemStates.isEmpty());
|
Q_ASSERT(!m_itemStates.isEmpty());
|
||||||
Q_ASSERT(m_plugin);
|
if (!m_plugin) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QMutexLocker pluginLocker(m_globalPluginMutex);
|
QMutexLocker pluginLocker(m_globalPluginMutex);
|
||||||
QMap<QString, QVector<VersionControlObserver::ItemState>>::iterator it = m_itemStates.begin();
|
QMap<QString, QVector<VersionControlObserver::ItemState>>::iterator it = m_itemStates.begin();
|
||||||
for (; it != m_itemStates.end(); ++it) {
|
for (; it != m_itemStates.end() && m_plugin; ++it) {
|
||||||
if (m_plugin->beginRetrieval(it.key())) {
|
if (m_plugin->beginRetrieval(it.key())) {
|
||||||
QVector<VersionControlObserver::ItemState> &items = it.value();
|
QVector<VersionControlObserver::ItemState> &items = it.value();
|
||||||
const int count = items.count();
|
const int count = items.count();
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count && m_plugin; ++i) {
|
||||||
const KFileItem &item = items.at(i).first;
|
const KFileItem &item = items.at(i).first;
|
||||||
const KVersionControlPlugin::ItemVersion version = m_plugin->itemVersion(item);
|
const KVersionControlPlugin::ItemVersion version = m_plugin->itemVersion(item);
|
||||||
items[i].second = version;
|
items[i].second = version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_plugin->endRetrieval();
|
if (m_plugin) {
|
||||||
|
m_plugin->endRetrieval();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "views/versioncontrol/versioncontrolobserver.h"
|
#include "views/versioncontrol/versioncontrolobserver.h"
|
||||||
|
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
#include <QPointer>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,7 +42,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMutex *m_globalPluginMutex; // Protects the m_plugin globally
|
QMutex *m_globalPluginMutex; // Protects the m_plugin globally
|
||||||
KVersionControlPlugin *m_plugin;
|
QPointer<KVersionControlPlugin> m_plugin;
|
||||||
|
|
||||||
QMap<QString, QVector<VersionControlObserver::ItemState>> m_itemStates;
|
QMap<QString, QVector<VersionControlObserver::ItemState>> m_itemStates;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user