summaryrefslogtreecommitdiff
path: root/plugins/autotest
diff options
context:
space:
mode:
authorChristian Stenger <christian.stenger@theqtcompany.com>2014-11-20 13:57:41 +0100
committerChristian Stenger <christian.stenger@theqtcompany.com>2014-12-04 13:52:16 +0100
commiteb073616fbac1d5f1f4c537ecc36047ea43f8b0e (patch)
tree2fa821c702283783bcc28513e39ac95f3d4b8332 /plugins/autotest
parent036c648650f646427be06e054371eb1971386fff (diff)
downloadqt-creator-eb073616fbac1d5f1f4c537ecc36047ea43f8b0e.tar.gz
Access test results list from multiple threads in a safe way
This had lead to crashes when executing projects with some more tests or more test output. Now it's using a mutex to avoid concurrent access.
Diffstat (limited to 'plugins/autotest')
-rw-r--r--plugins/autotest/testresultmodel.cpp16
-rw-r--r--plugins/autotest/testresultmodel.h2
2 files changed, 18 insertions, 0 deletions
diff --git a/plugins/autotest/testresultmodel.cpp b/plugins/autotest/testresultmodel.cpp
index 24a37c4886..1fe13b57e8 100644
--- a/plugins/autotest/testresultmodel.cpp
+++ b/plugins/autotest/testresultmodel.cpp
@@ -36,6 +36,7 @@ TestResultModel::TestResultModel(QObject *parent) :
TestResultModel::~TestResultModel()
{
+ QWriteLocker lock(&m_rwLock);
m_testResults.clear();
}
@@ -53,6 +54,7 @@ QModelIndex TestResultModel::parent(const QModelIndex &) const
int TestResultModel::rowCount(const QModelIndex &parent) const
{
+ // do not use the QReadLocker here or this will produce a deadlock
return parent.isValid() ? 0 : m_testResults.size();
}
@@ -80,6 +82,7 @@ static QIcon testResultIcon(ResultType result) {
QVariant TestResultModel::data(const QModelIndex &index, int role) const
{
+ QReadLocker lock(&m_rwLock);
if (!index.isValid() || index.row() >= m_testResults.count() || index.column() != 0)
return QVariant();
if (role == Qt::DisplayRole) {
@@ -106,8 +109,12 @@ QVariant TestResultModel::data(const QModelIndex &index, int role) const
void TestResultModel::addTestResult(const TestResult &testResult)
{
+ QReadLocker rLock(&m_rwLock);
beginInsertRows(QModelIndex(), m_testResults.size(), m_testResults.size());
+ rLock.unlock();
+ QWriteLocker wLock(&m_rwLock);
m_testResults.append(testResult);
+ wLock.unlock();
int count = m_testResultCount.value(testResult.result(), 0);
m_testResultCount.insert(testResult.result(), ++count);
endInsertRows();
@@ -116,10 +123,14 @@ void TestResultModel::addTestResult(const TestResult &testResult)
void TestResultModel::clearTestResults()
{
+ QReadLocker rLock(&m_rwLock);
if (m_testResults.size() == 0)
return;
beginRemoveRows(QModelIndex(), 0, m_testResults.size() - 1);
+ rLock.unlock();
+ QWriteLocker wLock(&m_rwLock);
m_testResults.clear();
+ wLock.unlock();
m_testResultCount.clear();
m_lastMaxWidthIndex = 0;
m_maxWidthOfFileName = 0;
@@ -132,12 +143,15 @@ TestResult TestResultModel::testResult(const QModelIndex &index) const
{
if (!index.isValid())
return TestResult(QString(), QString());
+ QReadLocker lock(&m_rwLock);
return m_testResults.at(index.row());
}
int TestResultModel::maxWidthOfFileName(const QFont &font)
{
+ QReadLocker lock(&m_rwLock);
int count = m_testResults.size();
+ lock.unlock();
if (count == 0)
return 0;
if (m_maxWidthOfFileName > 0 && font == m_measurementFont && m_lastMaxWidthIndex == count - 1)
@@ -147,7 +161,9 @@ int TestResultModel::maxWidthOfFileName(const QFont &font)
m_measurementFont = font;
for (int i = m_lastMaxWidthIndex; i < count; ++i) {
+ lock.relock();
QString filename = m_testResults.at(i).fileName();
+ lock.unlock();
const int pos = filename.lastIndexOf(QLatin1Char('/'));
if (pos != -1)
filename = filename.mid(pos +1);
diff --git a/plugins/autotest/testresultmodel.h b/plugins/autotest/testresultmodel.h
index 7618512fa2..1ef019a456 100644
--- a/plugins/autotest/testresultmodel.h
+++ b/plugins/autotest/testresultmodel.h
@@ -24,6 +24,7 @@
#include <QAbstractItemModel>
#include <QSortFilterProxyModel>
#include <QFont>
+#include <QReadWriteLock>
#include <QSet>
namespace Autotest {
@@ -65,6 +66,7 @@ private:
int m_lastMaxWidthIndex;
QFont m_measurementFont;
QSet<ResultType> m_availableResultTypes;
+ mutable QReadWriteLock m_rwLock;
};
class TestResultFilterModel : public QSortFilterProxyModel