diff options
author | Christian Stenger <christian.stenger@theqtcompany.com> | 2014-11-20 13:57:41 +0100 |
---|---|---|
committer | Christian Stenger <christian.stenger@theqtcompany.com> | 2014-12-04 13:52:16 +0100 |
commit | eb073616fbac1d5f1f4c537ecc36047ea43f8b0e (patch) | |
tree | 2fa821c702283783bcc28513e39ac95f3d4b8332 /plugins/autotest | |
parent | 036c648650f646427be06e054371eb1971386fff (diff) | |
download | qt-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.cpp | 16 | ||||
-rw-r--r-- | plugins/autotest/testresultmodel.h | 2 |
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 |