##// END OF EJS Templates
Add thread protection on AbortDownload process
perrinel -
r389:3698da027722
parent child
Show More
@@ -4,6 +4,7
4 #include <QNetworkAccessManager>
4 #include <QNetworkAccessManager>
5 #include <QNetworkReply>
5 #include <QNetworkReply>
6 #include <QNetworkRequest>
6 #include <QNetworkRequest>
7 #include <QReadWriteLock>
7 #include <QThread>
8 #include <QThread>
8
9
9 #include <unordered_map>
10 #include <unordered_map>
@@ -14,8 +15,13 struct NetworkController::NetworkControllerPrivate {
14 explicit NetworkControllerPrivate(NetworkController *parent) : m_WorkingMutex{} {}
15 explicit NetworkControllerPrivate(NetworkController *parent) : m_WorkingMutex{} {}
15 QMutex m_WorkingMutex;
16 QMutex m_WorkingMutex;
16
17
18 QReadWriteLock m_Lock;
17 std::unordered_map<QNetworkReply *, QUuid> m_NetworkReplyToVariableId;
19 std::unordered_map<QNetworkReply *, QUuid> m_NetworkReplyToVariableId;
18 std::unique_ptr<QNetworkAccessManager> m_AccessManager{nullptr};
20 std::unique_ptr<QNetworkAccessManager> m_AccessManager{nullptr};
21
22 void lockRead() { m_Lock.lockForRead(); }
23 void lockWrite() { m_Lock.lockForWrite(); }
24 void unlock() { m_Lock.unlock(); }
19 };
25 };
20
26
21 NetworkController::NetworkController(QObject *parent)
27 NetworkController::NetworkController(QObject *parent)
@@ -26,30 +32,50 NetworkController::NetworkController(QObject *parent)
26 void NetworkController::onProcessRequested(const QNetworkRequest &request, QUuid identifier,
32 void NetworkController::onProcessRequested(const QNetworkRequest &request, QUuid identifier,
27 std::function<void(QNetworkReply *, QUuid)> callback)
33 std::function<void(QNetworkReply *, QUuid)> callback)
28 {
34 {
29 qCInfo(LOG_NetworkController()) << tr("NetworkController registered")
30 << QThread::currentThread();
31 auto reply = impl->m_AccessManager->get(request);
35 auto reply = impl->m_AccessManager->get(request);
36 qCDebug(LOG_NetworkController()) << tr("NetworkController registered")
37 << QThread::currentThread() << reply;
32
38
33 // Store the couple reply id
39 // Store the couple reply id
40 impl->lockWrite();
34 impl->m_NetworkReplyToVariableId[reply] = identifier;
41 impl->m_NetworkReplyToVariableId[reply] = identifier;
42 impl->unlock();
35
43
36 auto onReplyFinished = [reply, this, identifier, callback]() {
44 auto onReplyFinished = [reply, this, identifier, callback]() {
37
45
38 qCInfo(LOG_NetworkController()) << tr("NetworkController onReplyFinished")
46 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyFinished")
39 << QThread::currentThread();
47 << QThread::currentThread() << reply;
48 impl->lockRead();
40 auto it = impl->m_NetworkReplyToVariableId.find(reply);
49 auto it = impl->m_NetworkReplyToVariableId.find(reply);
50 impl->unlock();
41 if (it != impl->m_NetworkReplyToVariableId.cend()) {
51 if (it != impl->m_NetworkReplyToVariableId.cend()) {
52 impl->lockWrite();
53 impl->m_NetworkReplyToVariableId.erase(reply);
54 impl->unlock();
55 // Deletes reply
42 callback(reply, identifier);
56 callback(reply, identifier);
57 reply->deleteLater();
58
59 emit this->replyDownloadProgress(identifier, 0);
43 }
60 }
61
62 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyFinished END")
63 << QThread::currentThread() << reply;
44 };
64 };
45
65
46 auto onReplyProgress = [reply, this](qint64 bytesRead, qint64 totalBytes) {
66 auto onReplyProgress = [reply, this](qint64 bytesRead, qint64 totalBytes) {
47
67
48 double progress = (bytesRead * 100.0) / totalBytes;
68 double progress = (bytesRead * 100.0) / totalBytes;
69 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress") << progress
70 << QThread::currentThread() << reply;
71 impl->lockRead();
49 auto it = impl->m_NetworkReplyToVariableId.find(reply);
72 auto it = impl->m_NetworkReplyToVariableId.find(reply);
73 impl->unlock();
50 if (it != impl->m_NetworkReplyToVariableId.cend()) {
74 if (it != impl->m_NetworkReplyToVariableId.cend()) {
51 emit this->replyDownloadProgress(it->second, progress);
75 emit this->replyDownloadProgress(it->second, progress);
52 }
76 }
77 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress END")
78 << QThread::currentThread() << reply;
53 };
79 };
54
80
55
81
@@ -73,12 +99,19 void NetworkController::finalize()
73 void NetworkController::onReplyCanceled(QUuid identifier)
99 void NetworkController::onReplyCanceled(QUuid identifier)
74 {
100 {
75 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
101 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
102 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled")
103 << QThread::currentThread();
104
76
105
106 impl->lockRead();
77 auto end = impl->m_NetworkReplyToVariableId.cend();
107 auto end = impl->m_NetworkReplyToVariableId.cend();
78 auto it = std::find_if(impl->m_NetworkReplyToVariableId.cbegin(), end, findReply);
108 auto it = std::find_if(impl->m_NetworkReplyToVariableId.cbegin(), end, findReply);
109 impl->unlock();
79 if (it != end) {
110 if (it != end) {
80 it->first->abort();
111 it->first->abort();
81 }
112 }
113 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled END")
114 << QThread::currentThread();
82 }
115 }
83
116
84 void NetworkController::waitForFinish()
117 void NetworkController::waitForFinish()
@@ -178,8 +178,8 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> vari
178 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
178 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
179 << QThread::currentThread()->objectName();
179 << QThread::currentThread()->objectName();
180
180
181 auto it = impl->m_VariableToIdentifier.find(variable);
181 auto it = impl->m_VariableToIdentifierMap.find(variable);
182 if (it != impl->m_VariableToIdentifier.cend()) {
182 if (it != impl->m_VariableToIdentifierMap.cend()) {
183 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
183 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
184 }
184 }
185 else {
185 else {
General Comments 3
Under Review
author

Pull request updated. Auto status change to "Under Review"

Changed commits:
  * 3 added
  * 0 removed

Changed files:
  * A plugins/amda/tests-resources/TestAmdaResultParser/FileNotFound.txt
  * M gui/src/Visualization/operations/RescaleAxeOperation.cpp
  * M app/src/MainWindow.cpp
  * M core/include/Data/IDataProvider.h
  * M core/include/DataSource/DataSourceItemAction.h
  * M core/include/Variable/VariableController.h
  * M core/include/Variable/VariableModel.h
  * M core/include/Visualization/VisualizationController.h
  * M core/src/Network/NetworkController.cpp
  * M core/src/Variable/Variable.cpp
  * M core/src/Variable/VariableController.cpp
  * M core/src/Variable/VariableModel.cpp
  * M gui/include/Visualization/VisualizationGraphWidget.h
  * M gui/include/Visualization/VisualizationWidget.h
  * M gui/src/SqpApplication.cpp
  * M gui/src/Variable/VariableInspectorWidget.cpp
  * M gui/src/Visualization/VisualizationGraphHelper.cpp
  * M gui/src/Visualization/VisualizationGraphWidget.cpp
  * M gui/src/Visualization/VisualizationWidget.cpp
  * M gui/src/Visualization/VisualizationZoneWidget.cpp
  * M plugins/amda/include/AmdaProvider.h
  * M plugins/amda/src/AmdaProvider.cpp
  * M plugins/amda/src/AmdaResultParser.cpp
  * M plugins/amda/tests/TestAmdaResultParser.cpp
  * M plugins/mockplugin/include/CosinusProvider.h
  * M plugins/mockplugin/src/CosinusProvider.cpp
  * R COPYING
  * R app/ui/MainWindow.ui
  * R cmake/sciqlop_package_qt.cmake
  * R core/include/Common/MetaTypes.h
  * R core/include/Data/ArrayData.h
  * R core/include/Data/DataProviderParameters.h
  * R core/include/Data/DataSeries.h
  * R core/include/Data/IDataSeries.h
  * R core/include/Data/ScalarSeries.h
  * R core/include/Data/SqpDateTime.h
  * R core/include/Network/NetworkController.h
  * R core/include/Plugin/PluginManager.h
  * R core/include/Time/TimeController.h
  * R core/include/Variable/Variable.h
  * R core/include/Variable/VariableCacheController.h
  * R core/src/Data/ScalarSeries.cpp
  * R core/src/DataSource/DataSourceItemAction.cpp
  * R core/src/Plugin/PluginManager.cpp
  * R core/src/Time/TimeController.cpp
  * R core/src/Variable/VariableCacheController.cpp
  * R core/src/Visualization/VisualizationController.cpp
  * R core/tests/Variable/TestVariableCacheController.cpp
  * R gui/include/DataSource/DataSourceTreeWidgetItem.h
  * R gui/include/DataSource/DataSourceWidget.h
  * R gui/include/SidePane/SqpSidePane.h
  * R gui/include/TimeWidget/TimeWidget.h
  * R gui/include/Variable/VariableInspectorWidget.h
  * R gui/include/Variable/VariableMenuHeaderWidget.h
  * R gui/include/Visualization/IVariableContainer.h
  * R gui/include/Visualization/IVisualizationWidget.h
  * R gui/include/Visualization/IVisualizationWidgetVisitor.h
  * R gui/include/Visualization/VisualizationGraphHelper.h
  * R gui/include/Visualization/VisualizationTabWidget.h
  * R gui/include/Visualization/VisualizationZoneWidget.h
  * R gui/include/Visualization/operations/GenerateVariableMenuOperation.h
  * R gui/include/Visualization/operations/MenuBuilder.h
  * R gui/include/Visualization/operations/RemoveVariableOperation.h
  * R gui/include/Visualization/qcustomplot.h
  * R gui/resources/icones/dataSourceComponent.png
  * R gui/resources/icones/dataSourceNode.png
  * R gui/resources/icones/dataSourceProduct.png
  * R gui/resources/icones/dataSourceRoot.png
  * R gui/resources/icones/delete.png
  * R gui/resources/icones/next.png
  * R gui/resources/icones/openInspector.png
  * R gui/resources/icones/plot.png
  * R gui/resources/icones/previous.png
  * R gui/resources/icones/sciqlop2PNG_1024.png
  * R gui/resources/icones/unplot.png
  * R gui/resources/sqpguiresources.qrc
  * R gui/src/DataSource/DataSourceTreeWidgetItem.cpp
  * R gui/src/DataSource/DataSourceWidget.cpp
  * R gui/src/SidePane/SqpSidePane.cpp
  * R gui/src/TimeWidget/TimeWidget.cpp
  * R gui/src/Variable/VariableMenuHeaderWidget.cpp
  * R gui/src/Visualization/VisualizationTabWidget.cpp
  * R gui/src/Visualization/operations/GenerateVariableMenuOperation.cpp
  * R gui/src/Visualization/operations/MenuBuilder.cpp
  * R gui/src/Visualization/operations/RemoveVariableOperation.cpp
  * R gui/src/Visualization/qcustomplot.cpp
  * R gui/ui/DataSource/DataSourceWidget.ui
  * R gui/ui/SidePane/SqpSidePane.ui
  * R gui/ui/TimeWidget/TimeWidget.ui
  * R gui/ui/Variable/VariableInspectorWidget.ui
  * R gui/ui/Variable/VariableMenuHeaderWidget.ui
  * R gui/ui/Visualization/VisualizationGraphWidget.ui
  * R gui/ui/Visualization/VisualizationTabWidget.ui
  * R gui/ui/Visualization/VisualizationWidget.ui
  * R gui/ui/Visualization/VisualizationZoneWidget.ui
  * R gui/vera-exclusions/exclusions.txt
  * R plugin/CMakeLists.txt
  * R plugin/cmake/Findsciqlop-plugin.cmake
  * R plugin/include/Plugin/IPlugin.h
  * R plugins/amda/CMakeLists.txt
  * R plugins/amda/cmake/Findsciqlop-amda.cmake
  * R plugins/amda/include/AmdaDefs.h
  * R plugins/amda/include/AmdaGlobal.h
  * R plugins/amda/include/AmdaParser.h
  * R plugins/amda/include/AmdaPlugin.h
  * R plugins/amda/include/AmdaResultParser.h
  * R plugins/amda/resources/amda.json
  * R plugins/amda/resources/amdaresources.qrc
  * R plugins/amda/resources/samples/AmdaSample.json
  * R plugins/amda/src/AmdaDefs.cpp
  * R plugins/amda/src/AmdaParser.cpp
  * R plugins/amda/src/AmdaPlugin.cpp
  * R plugins/amda/tests-resources/TestAmdaParser/TwoRootsFile.json
  * R plugins/amda/tests-resources/TestAmdaParser/ValidFile1.json
  * R plugins/amda/tests-resources/TestAmdaParser/WrongRootKey.json
  * R plugins/amda/tests-resources/TestAmdaParser/WrongRootType.json
  * R plugins/amda/tests-resources/TestAmdaResultParser/NaNValue.txt
  * R plugins/amda/tests-resources/TestAmdaResultParser/NoUnit.txt
  * R plugins/amda/tests-resources/TestAmdaResultParser/TooManyValues.txt
  * R plugins/amda/tests-resources/TestAmdaResultParser/ValidScalar1.txt
  * R plugins/amda/tests-resources/TestAmdaResultParser/WrongDate.txt
  * R plugins/amda/tests-resources/TestAmdaResultParser/WrongUnit.txt
  * R plugins/amda/tests-resources/TestAmdaResultParser/WrongValue.txt
  * R plugins/amda/tests/TestAmdaParser.cpp
  * R plugins/mockplugin/CMakeLists.txt
  * R plugins/mockplugin/cmake/Findsciqlop-mockplugin.cmake
  * R plugins/mockplugin/include/MockPlugin.h
  * R plugins/mockplugin/include/MockPluginGlobal.h
  * R plugins/mockplugin/resources/mockplugin.json
  * R plugins/mockplugin/src/MockPlugin.cpp
  * R README.md
  * R app/CMakeLists.txt
  * R app/include/MainWindow.h
  * R app/src/Main.cpp
  * R app/vera-exclusions/exclusions.txt
  * R cmake/sciqlop.cmake
  * R cmake/sciqlop_applications.cmake
  * R cmake/sciqlop_package.cmake
  * R cmake/sciqlop_params.cmake
  * R core/CMakeLists.txt
  * R core/include/Common/spimpl.h
  * R core/include/DataSource/DataSourceController.h
  * R core/include/DataSource/DataSourceItem.h
  * R core/src/DataSource/DataSourceController.cpp
  * R core/src/DataSource/DataSourceItem.cpp
  * R core/tests/DataSource/TestDataSourceController.cpp
  * R core/vera-exclusions/exclusions.txt
  * R formatting/cmake/use_clangformat.cmake
  * R formatting/vera-exclusions/exclusions.txt
  * R gui/CMakeLists.txt
  * R gui/include/SqpApplication.h
  * R LICENSE
  * R app/src/mainwindow.cpp
  * R app/src/mainwindow.ui
Approved
author

Status change > Approved

You need to be logged in to leave comments. Login now