We don't need the mutex guarding m_itemStates in the

UpdateItemStatesThread, because m_itemStates is only accessed by the
when the thread is done, and set before the thread starts.

Also combine the setData function with the constructor.
This commit is contained in:
Simeon Bird 2013-01-12 10:37:26 -05:00
parent 72de114a94
commit 7fe1278b1e
3 changed files with 14 additions and 38 deletions

View file

@ -23,13 +23,13 @@
#include <QMutexLocker>
UpdateItemStatesThread::UpdateItemStatesThread() :
UpdateItemStatesThread::UpdateItemStatesThread(KVersionControlPlugin* plugin,
const QList<VersionControlObserver::ItemState>& itemStates) :
QThread(),
m_globalPluginMutex(0),
m_plugin(0),
m_itemMutex(),
m_plugin(plugin),
m_retrievedItems(false),
m_itemStates()
m_itemStates(itemStates)
{
// Several threads may share one instance of a plugin. A global
// mutex is required to serialize the retrieval of version control
@ -42,32 +42,16 @@ UpdateItemStatesThread::~UpdateItemStatesThread()
{
}
void UpdateItemStatesThread::setData(KVersionControlPlugin* plugin,
const QList<VersionControlObserver::ItemState>& itemStates)
{
// The locks are taken in the same order as in run()
// to avoid potential deadlock.
QMutexLocker pluginLocker(m_globalPluginMutex);
QMutexLocker itemLocker(&m_itemMutex);
m_itemStates = itemStates;
m_plugin = plugin;
}
void UpdateItemStatesThread::run()
{
Q_ASSERT(!m_itemStates.isEmpty());
Q_ASSERT(m_plugin);
QMutexLocker itemLocker(&m_itemMutex);
const QString directory = m_itemStates.first().item.url().directory(KUrl::AppendTrailingSlash);
m_retrievedItems = false;
itemLocker.unlock();
QMutexLocker pluginLocker(m_globalPluginMutex);
if (m_plugin->beginRetrieval(directory)) {
itemLocker.relock();
const int count = m_itemStates.count();
KVersionControlPlugin2* pluginV2 = qobject_cast<KVersionControlPlugin2*>(m_plugin);
@ -99,13 +83,11 @@ void UpdateItemStatesThread::unlockPlugin()
QList<VersionControlObserver::ItemState> UpdateItemStatesThread::itemStates() const
{
QMutexLocker locker(&m_itemMutex);
return m_itemStates;
}
bool UpdateItemStatesThread::retrievedItems() const
{
QMutexLocker locker(&m_itemMutex);
return m_retrievedItems;
}

View file

@ -38,9 +38,6 @@ class LIBDOLPHINPRIVATE_EXPORT UpdateItemStatesThread : public QThread
Q_OBJECT
public:
UpdateItemStatesThread();
virtual ~UpdateItemStatesThread();
/**
* @param plugin Version control plugin that is used to update the
* state of the items. Whenever the plugin is accessed
@ -49,8 +46,9 @@ public:
* UpdateItemStatesThread::unlockPlugin() must be used.
* @param itemStates List of items, where the states get updated.
*/
void setData(KVersionControlPlugin* plugin,
const QList<VersionControlObserver::ItemState>& itemStates);
UpdateItemStatesThread(KVersionControlPlugin* plugin,
const QList<VersionControlObserver::ItemState>& itemStates);
virtual ~UpdateItemStatesThread();
/**
* Whenever the plugin is accessed by the thread creator, lockPlugin() must
@ -76,7 +74,6 @@ private:
QMutex* m_globalPluginMutex; // Protects the m_plugin globally
KVersionControlPlugin* m_plugin;
mutable QMutex m_itemMutex; // Protects m_retrievedItems and m_itemStates
bool m_retrievedItems;
QList<VersionControlObserver::ItemState> m_itemStates;
};

View file

@ -238,20 +238,12 @@ void VersionControlObserver::slotThreadFinished()
void VersionControlObserver::updateItemStates()
{
Q_ASSERT(m_plugin);
if (!m_updateItemStatesThread) {
m_updateItemStatesThread = new UpdateItemStatesThread();
connect(m_updateItemStatesThread, SIGNAL(finished()),
this, SLOT(slotThreadFinished()));
connect(m_updateItemStatesThread, SIGNAL(finished()),
m_updateItemStatesThread, SLOT(deleteLater()));
}
else {
if (m_updateItemStatesThread) {
// An update is currently ongoing. Wait until the thread has finished
// the update (see slotThreadFinished()).
m_pendingItemStatesUpdate = true;
return;
}
QList<ItemState> itemStates;
const int itemCount = m_model->count();
itemStates.reserve(itemCount);
@ -269,7 +261,12 @@ void VersionControlObserver::updateItemStates()
if (!m_silentUpdate) {
emit infoMessage(i18nc("@info:status", "Updating version information..."));
}
m_updateItemStatesThread->setData(m_plugin, itemStates);
m_updateItemStatesThread = new UpdateItemStatesThread(m_plugin, itemStates);
connect(m_updateItemStatesThread, SIGNAL(finished()),
this, SLOT(slotThreadFinished()));
connect(m_updateItemStatesThread, SIGNAL(finished()),
m_updateItemStatesThread, SLOT(deleteLater()));
m_updateItemStatesThread->start(); // slotThreadFinished() is called when finished
}
}