* add mutex to avoid crash on qhash data update (#62)

* update gitignore
* update contributing.md
This commit is contained in:
arcan1s 2015-10-11 18:28:21 +03:00
parent 440d180c20
commit d3ab0a7228
4 changed files with 72 additions and 23 deletions

48
.gitignore vendored
View File

@ -1,7 +1,49 @@
sources/build # Compiled Object files
sources/usr *.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
# cmake
CMakeCache.txt
CMakeFiles
CMakeScripts
Makefile
cmake_install.cmake
install_manifest.txt
# build directory
build
# archives
*src.tar.[gx]z *src.tar.[gx]z
*pkg.tar.[gx]z *pkg.tar.[gx]z
build
src src
pkg pkg
# idea
.idea

View File

@ -63,7 +63,7 @@ for more details. Some additional detail see below.
recommended. recommended.
* New lines rules: * New lines rules:
* One line after license header. * One line after license header.
* One line between header group declaration (see above). * One line between header group declaration (see above) (only for source files).
* Two lines after header declaration and before declaration at the end of a * Two lines after header declaration and before declaration at the end of a
file. file.
* One line after class and types forward declaration in headers. * One line after class and types forward declaration in headers.
@ -75,6 +75,9 @@ for more details. Some additional detail see below.
* Class constructor should have default arguments. Use `QObject *parent` property * Class constructor should have default arguments. Use `QObject *parent` property
for QObject based classes. for QObject based classes.
* QObject based classes constructors should have explicit modifier. * QObject based classes constructors should have explicit modifier.
* Create one file (source and header) per class.
* `else if` construction is allowed and recommended.
* 'true ? foo : bar' construction is allowed and recommended for one-line assignment.
Comments Comments
-------- --------

View File

@ -49,8 +49,8 @@ AWKeys::AWKeys(QObject *parent)
#ifdef BUILD_FUTURE #ifdef BUILD_FUTURE
// thread pool // thread pool
queueLimit = 2 * QThread::idealThreadCount(); m_queueLimit = 2 * QThread::idealThreadCount();
threadPool = new QThreadPool(this); m_threadPool = new QThreadPool(this);
#endif /* BUILD_FUTURE */ #endif /* BUILD_FUTURE */
aggregator = new AWKeysAggregator(this); aggregator = new AWKeysAggregator(this);
@ -75,7 +75,7 @@ AWKeys::~AWKeys()
// core // core
if (dataEngineAggregator != nullptr) delete dataEngineAggregator; if (dataEngineAggregator != nullptr) delete dataEngineAggregator;
if (threadPool != nullptr) delete threadPool; if (m_threadPool != nullptr) delete m_threadPool;
delete aggregator; delete aggregator;
delete dataAggregator; delete dataAggregator;
} }
@ -85,8 +85,8 @@ void AWKeys::unlock()
{ {
qCDebug(LOG_AW); qCDebug(LOG_AW);
qCWarning(LOG_AW) << "Unlock stream"; qCWarning(LOG_AW) << "Unm_lock stream";
lock = false; m_lock = false;
} }
@ -115,9 +115,9 @@ void AWKeys::initKeys(const QString currentPattern, const int interval, const in
} else } else
dataEngineAggregator->setInterval(interval); dataEngineAggregator->setInterval(interval);
#ifdef BUILD_FUTURE #ifdef BUILD_FUTURE
int rawLimit = (limit == 0 ? QThread::idealThreadCount() : limit); int rawLimit = limit == 0 ? QThread::idealThreadCount() : limit;
queueLimit = 2 * rawLimit; m_queueLimit = 2 * rawLimit;
threadPool->setMaxThreadCount(rawLimit); m_threadPool->setMaxThreadCount(rawLimit);
#endif /* BUILD_FUTURE */ #endif /* BUILD_FUTURE */
updateCache(); updateCache();
@ -177,7 +177,7 @@ QStringList AWKeys::dictKeys(const bool sorted, const QString regexp) const
// uptime // uptime
allKeys.append(QString("uptime")); allKeys.append(QString("uptime"));
allKeys.append(QString("cuptime")); allKeys.append(QString("cuptime"));
// cpuclock & cpu // cpucm_lock & cpu
for (int i=QThread::idealThreadCount()-1; i>=0; i--) { for (int i=QThread::idealThreadCount()-1; i>=0; i--) {
allKeys.append(QString("cpucl%1").arg(i)); allKeys.append(QString("cpucl%1").arg(i));
allKeys.append(QString("cpu%1").arg(i)); allKeys.append(QString("cpu%1").arg(i));
@ -410,14 +410,14 @@ void AWKeys::dataUpdated(const QString sourceName, const QVariant value, const Q
qCDebug(LOG_AW) << "Source" << sourceName; qCDebug(LOG_AW) << "Source" << sourceName;
qCDebug(LOG_AW) << "Data" << value << units; qCDebug(LOG_AW) << "Data" << value << units;
if (lock) if (m_lock)
return; return;
if (sourceName == QString("update")) if (sourceName == QString("update"))
return emit(needToBeUpdated()); return emit(needToBeUpdated());
#ifdef BUILD_FUTURE #ifdef BUILD_FUTURE
// run concurrent data update // run concurrent data update
QtConcurrent::run(threadPool, this, &AWKeys::setDataBySource, sourceName, value, units); QtConcurrent::run(m_threadPool, this, &AWKeys::setDataBySource, sourceName, value, units);
#else /* BUILD_FUTURE */ #else /* BUILD_FUTURE */
return setDataBySource(sourceName, value, units); return setDataBySource(sourceName, value, units);
#endif /* BUILD_FUTURE */ #endif /* BUILD_FUTURE */
@ -538,7 +538,7 @@ void AWKeys::updateTextData()
qCDebug(LOG_AW); qCDebug(LOG_AW);
#ifdef BUILD_FUTURE #ifdef BUILD_FUTURE
QFuture<QString> text = QtConcurrent::run(threadPool, [this]() { QFuture<QString> text = QtConcurrent::run(m_threadPool, [this]() {
calculateValues(); calculateValues();
return parsePattern(m_pattern); return parsePattern(m_pattern);
}); });
@ -716,9 +716,9 @@ void AWKeys::setDataBySource(const QString sourceName, const QVariant value, con
#ifdef BUILD_FUTURE #ifdef BUILD_FUTURE
// drop if limits are reached // drop if limits are reached
if (++queue > queueLimit) { if (++m_queue > m_queueLimit) {
qCWarning(LOG_AW) << "Messages queue" << queue-- << "more than limits" << queueLimit; qCWarning(LOG_AW) << "Messages m_queue" << m_queue-- << "more than limits" << m_queueLimit;
lock = true; m_lock = true;
return dataEngineAggregator->disconnectVisualization(); return dataEngineAggregator->disconnectVisualization();
} }
#endif /* BUILD_FUTURE */ #endif /* BUILD_FUTURE */
@ -733,12 +733,14 @@ void AWKeys::setDataBySource(const QString sourceName, const QVariant value, con
qCDebug(LOG_AW) << "Source" << sourceName << "not found"; qCDebug(LOG_AW) << "Source" << sourceName << "not found";
emit(dropSourceFromDataengine(sourceName)); emit(dropSourceFromDataengine(sourceName));
} else { } else {
m_mutex.lock();
std::for_each(tags.cbegin(), tags.cend(), [this, value](const QString tag) { std::for_each(tags.cbegin(), tags.cend(), [this, value](const QString tag) {
values[tag] = aggregator->formater(value, tag); values[tag] = aggregator->formater(value, tag);
}); });
m_mutex.unlock();
} }
#ifdef BUILD_FUTURE #ifdef BUILD_FUTURE
queue--; m_queue--;
#endif /* BUILD_FUTURE */ #endif /* BUILD_FUTURE */
} }

View File

@ -19,6 +19,7 @@
#ifndef AWKEYS_H #ifndef AWKEYS_H
#define AWKEYS_H #define AWKEYS_H
#include <QMutex>
#include <QObject> #include <QObject>
#include "extitemaggregator.h" #include "extitemaggregator.h"
@ -95,9 +96,10 @@ private:
QHash<QString, QString> values; QHash<QString, QString> values;
bool m_wrapNewLines = false; bool m_wrapNewLines = false;
// queue and stream lock properties // queue and stream lock properties
QThreadPool *threadPool = nullptr; QThreadPool *m_threadPool = nullptr;
int queueLimit, queue = 0; QMutex m_mutex;
bool lock = true; int m_queueLimit, m_queue = 0;
bool m_lock = true;
}; };