##// END OF EJS Templates
Add thread protection on AbortDownload process
perrinel -
r423:3698da027722
parent child
Show More
@@ -1,87 +1,120
1 #include "Network/NetworkController.h"
1 #include "Network/NetworkController.h"
2
2
3 #include <QMutex>
3 #include <QMutex>
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>
10
11
11 Q_LOGGING_CATEGORY(LOG_NetworkController, "NetworkController")
12 Q_LOGGING_CATEGORY(LOG_NetworkController, "NetworkController")
12
13
13 struct NetworkController::NetworkControllerPrivate {
14 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)
22 : QObject(parent), impl{spimpl::make_unique_impl<NetworkControllerPrivate>(this)}
28 : QObject(parent), impl{spimpl::make_unique_impl<NetworkControllerPrivate>(this)}
23 {
29 {
24 }
30 }
25
31
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
56 connect(reply, &QNetworkReply::finished, this, onReplyFinished);
82 connect(reply, &QNetworkReply::finished, this, onReplyFinished);
57 connect(reply, &QNetworkReply::downloadProgress, this, onReplyProgress);
83 connect(reply, &QNetworkReply::downloadProgress, this, onReplyProgress);
58 }
84 }
59
85
60 void NetworkController::initialize()
86 void NetworkController::initialize()
61 {
87 {
62 qCDebug(LOG_NetworkController()) << tr("NetworkController init") << QThread::currentThread();
88 qCDebug(LOG_NetworkController()) << tr("NetworkController init") << QThread::currentThread();
63 impl->m_WorkingMutex.lock();
89 impl->m_WorkingMutex.lock();
64 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
90 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
65 qCDebug(LOG_NetworkController()) << tr("NetworkController init END");
91 qCDebug(LOG_NetworkController()) << tr("NetworkController init END");
66 }
92 }
67
93
68 void NetworkController::finalize()
94 void NetworkController::finalize()
69 {
95 {
70 impl->m_WorkingMutex.unlock();
96 impl->m_WorkingMutex.unlock();
71 }
97 }
72
98
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()
85 {
118 {
86 QMutexLocker locker{&impl->m_WorkingMutex};
119 QMutexLocker locker{&impl->m_WorkingMutex};
87 }
120 }
@@ -1,238 +1,238
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableCacheController.h>
2 #include <Variable/VariableCacheController.h>
3 #include <Variable/VariableController.h>
3 #include <Variable/VariableController.h>
4 #include <Variable/VariableModel.h>
4 #include <Variable/VariableModel.h>
5
5
6 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
7 #include <Data/IDataProvider.h>
7 #include <Data/IDataProvider.h>
8 #include <Data/IDataSeries.h>
8 #include <Data/IDataSeries.h>
9 #include <Time/TimeController.h>
9 #include <Time/TimeController.h>
10
10
11 #include <QDateTime>
11 #include <QDateTime>
12 #include <QMutex>
12 #include <QMutex>
13 #include <QThread>
13 #include <QThread>
14 #include <QUuid>
14 #include <QUuid>
15 #include <QtCore/QItemSelectionModel>
15 #include <QtCore/QItemSelectionModel>
16
16
17 #include <unordered_map>
17 #include <unordered_map>
18
18
19 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
19 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
20
20
21 struct VariableController::VariableControllerPrivate {
21 struct VariableController::VariableControllerPrivate {
22 explicit VariableControllerPrivate(VariableController *parent)
22 explicit VariableControllerPrivate(VariableController *parent)
23 : m_WorkingMutex{},
23 : m_WorkingMutex{},
24 m_VariableModel{new VariableModel{parent}},
24 m_VariableModel{new VariableModel{parent}},
25 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
25 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
26 m_VariableCacheController{std::make_unique<VariableCacheController>()}
26 m_VariableCacheController{std::make_unique<VariableCacheController>()}
27 {
27 {
28 }
28 }
29
29
30 QMutex m_WorkingMutex;
30 QMutex m_WorkingMutex;
31 /// Variable model. The VariableController has the ownership
31 /// Variable model. The VariableController has the ownership
32 VariableModel *m_VariableModel;
32 VariableModel *m_VariableModel;
33 QItemSelectionModel *m_VariableSelectionModel;
33 QItemSelectionModel *m_VariableSelectionModel;
34
34
35
35
36 TimeController *m_TimeController{nullptr};
36 TimeController *m_TimeController{nullptr};
37 std::unique_ptr<VariableCacheController> m_VariableCacheController;
37 std::unique_ptr<VariableCacheController> m_VariableCacheController;
38
38
39 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
39 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
40 m_VariableToProviderMap;
40 m_VariableToProviderMap;
41 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
41 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
42 };
42 };
43
43
44 VariableController::VariableController(QObject *parent)
44 VariableController::VariableController(QObject *parent)
45 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
45 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
46 {
46 {
47 qCDebug(LOG_VariableController()) << tr("VariableController construction")
47 qCDebug(LOG_VariableController()) << tr("VariableController construction")
48 << QThread::currentThread();
48 << QThread::currentThread();
49
49
50 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
50 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
51 &VariableController::onAbortProgressRequested);
51 &VariableController::onAbortProgressRequested);
52 }
52 }
53
53
54 VariableController::~VariableController()
54 VariableController::~VariableController()
55 {
55 {
56 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
56 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
57 << QThread::currentThread();
57 << QThread::currentThread();
58 this->waitForFinish();
58 this->waitForFinish();
59 }
59 }
60
60
61 VariableModel *VariableController::variableModel() noexcept
61 VariableModel *VariableController::variableModel() noexcept
62 {
62 {
63 return impl->m_VariableModel;
63 return impl->m_VariableModel;
64 }
64 }
65
65
66 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
66 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
67 {
67 {
68 return impl->m_VariableSelectionModel;
68 return impl->m_VariableSelectionModel;
69 }
69 }
70
70
71 void VariableController::setTimeController(TimeController *timeController) noexcept
71 void VariableController::setTimeController(TimeController *timeController) noexcept
72 {
72 {
73 impl->m_TimeController = timeController;
73 impl->m_TimeController = timeController;
74 }
74 }
75
75
76 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
76 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
77 {
77 {
78 if (!variable) {
78 if (!variable) {
79 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
79 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
80 return;
80 return;
81 }
81 }
82
82
83 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
83 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
84 // make some treatments before the deletion
84 // make some treatments before the deletion
85 emit variableAboutToBeDeleted(variable);
85 emit variableAboutToBeDeleted(variable);
86
86
87 // Deletes identifier
87 // Deletes identifier
88 impl->m_VariableToIdentifierMap.erase(variable);
88 impl->m_VariableToIdentifierMap.erase(variable);
89
89
90 // Deletes provider
90 // Deletes provider
91 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
91 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
92 qCDebug(LOG_VariableController())
92 qCDebug(LOG_VariableController())
93 << tr("Number of providers deleted for variable %1: %2")
93 << tr("Number of providers deleted for variable %1: %2")
94 .arg(variable->name(), QString::number(nbProvidersDeleted));
94 .arg(variable->name(), QString::number(nbProvidersDeleted));
95
95
96 // Clears cache
96 // Clears cache
97 impl->m_VariableCacheController->clear(variable);
97 impl->m_VariableCacheController->clear(variable);
98
98
99 // Deletes from model
99 // Deletes from model
100 impl->m_VariableModel->deleteVariable(variable);
100 impl->m_VariableModel->deleteVariable(variable);
101 }
101 }
102
102
103 void VariableController::deleteVariables(
103 void VariableController::deleteVariables(
104 const QVector<std::shared_ptr<Variable> > &variables) noexcept
104 const QVector<std::shared_ptr<Variable> > &variables) noexcept
105 {
105 {
106 for (auto variable : qAsConst(variables)) {
106 for (auto variable : qAsConst(variables)) {
107 deleteVariable(variable);
107 deleteVariable(variable);
108 }
108 }
109 }
109 }
110
110
111 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
111 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
112 {
112 {
113 }
113 }
114
114
115 void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
115 void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
116 std::shared_ptr<IDataProvider> provider) noexcept
116 std::shared_ptr<IDataProvider> provider) noexcept
117 {
117 {
118
118
119 if (!impl->m_TimeController) {
119 if (!impl->m_TimeController) {
120 qCCritical(LOG_VariableController())
120 qCCritical(LOG_VariableController())
121 << tr("Impossible to create variable: The time controller is null");
121 << tr("Impossible to create variable: The time controller is null");
122 return;
122 return;
123 }
123 }
124
124
125 auto dateTime = impl->m_TimeController->dateTime();
125 auto dateTime = impl->m_TimeController->dateTime();
126
126
127 if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime, metadata)) {
127 if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime, metadata)) {
128 auto identifier = QUuid::createUuid();
128 auto identifier = QUuid::createUuid();
129
129
130 // store the provider
130 // store the provider
131 impl->m_VariableToProviderMap[newVariable] = provider;
131 impl->m_VariableToProviderMap[newVariable] = provider;
132 impl->m_VariableToIdentifierMap[newVariable] = identifier;
132 impl->m_VariableToIdentifierMap[newVariable] = identifier;
133
133
134 auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ](
134 auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ](
135 QUuid identifier, auto dataSeriesAcquired, auto dateTimeToPutInCache)
135 QUuid identifier, auto dataSeriesAcquired, auto dateTimeToPutInCache)
136 {
136 {
137 if (auto variable = varW.lock()) {
137 if (auto variable = varW.lock()) {
138 auto varIdentifier = impl->m_VariableToIdentifierMap.at(variable);
138 auto varIdentifier = impl->m_VariableToIdentifierMap.at(variable);
139 if (varIdentifier == identifier) {
139 if (varIdentifier == identifier) {
140 impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache);
140 impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache);
141 variable->setDataSeries(dataSeriesAcquired);
141 variable->setDataSeries(dataSeriesAcquired);
142 }
142 }
143 }
143 }
144 };
144 };
145
145
146 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
146 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
147 this->onRequestDataLoading(newVariable, dateTime);
147 this->onRequestDataLoading(newVariable, dateTime);
148 }
148 }
149 }
149 }
150
150
151 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
151 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
152 {
152 {
153 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
153 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
154 << QThread::currentThread()->objectName();
154 << QThread::currentThread()->objectName();
155 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
155 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
156
156
157 for (const auto &selectedRow : qAsConst(selectedRows)) {
157 for (const auto &selectedRow : qAsConst(selectedRows)) {
158 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
158 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
159 selectedVariable->setDateTime(dateTime);
159 selectedVariable->setDateTime(dateTime);
160 this->onRequestDataLoading(selectedVariable, dateTime);
160 this->onRequestDataLoading(selectedVariable, dateTime);
161 }
161 }
162 }
162 }
163 }
163 }
164
164
165 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
165 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
166 {
166 {
167 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
167 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
168
168
169 auto end = impl->m_VariableToIdentifierMap.cend();
169 auto end = impl->m_VariableToIdentifierMap.cend();
170 auto it = std::find_if(impl->m_VariableToIdentifierMap.cbegin(), end, findReply);
170 auto it = std::find_if(impl->m_VariableToIdentifierMap.cbegin(), end, findReply);
171 if (it != end) {
171 if (it != end) {
172 impl->m_VariableModel->setDataProgress(it->first, progress);
172 impl->m_VariableModel->setDataProgress(it->first, progress);
173 }
173 }
174 }
174 }
175
175
176 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
176 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
177 {
177 {
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 {
186 qCWarning(LOG_VariableController())
186 qCWarning(LOG_VariableController())
187 << tr("Aborting progression of inexistant variable detected !!!")
187 << tr("Aborting progression of inexistant variable detected !!!")
188 << QThread::currentThread()->objectName();
188 << QThread::currentThread()->objectName();
189 }
189 }
190 }
190 }
191
191
192
192
193 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
193 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
194 const SqpDateTime &dateTime)
194 const SqpDateTime &dateTime)
195 {
195 {
196 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
196 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
197 << QThread::currentThread()->objectName();
197 << QThread::currentThread()->objectName();
198 // we want to load data of the variable for the dateTime.
198 // we want to load data of the variable for the dateTime.
199 // First we check if the cache contains some of them.
199 // First we check if the cache contains some of them.
200 // For the other, we ask the provider to give them.
200 // For the other, we ask the provider to give them.
201 if (variable) {
201 if (variable) {
202
202
203 auto dateTimeListNotInCache
203 auto dateTimeListNotInCache
204 = impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime);
204 = impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime);
205
205
206 if (!dateTimeListNotInCache.empty()) {
206 if (!dateTimeListNotInCache.empty()) {
207 // Ask the provider for each data on the dateTimeListNotInCache
207 // Ask the provider for each data on the dateTimeListNotInCache
208 auto identifier = impl->m_VariableToIdentifierMap.at(variable);
208 auto identifier = impl->m_VariableToIdentifierMap.at(variable);
209 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
209 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
210 identifier,
210 identifier,
211 DataProviderParameters{std::move(dateTimeListNotInCache), variable->metadata()});
211 DataProviderParameters{std::move(dateTimeListNotInCache), variable->metadata()});
212 }
212 }
213 else {
213 else {
214 emit variable->updated();
214 emit variable->updated();
215 }
215 }
216 }
216 }
217 else {
217 else {
218 qCCritical(LOG_VariableController()) << tr("Impossible to load data of a variable null");
218 qCCritical(LOG_VariableController()) << tr("Impossible to load data of a variable null");
219 }
219 }
220 }
220 }
221
221
222
222
223 void VariableController::initialize()
223 void VariableController::initialize()
224 {
224 {
225 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
225 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
226 impl->m_WorkingMutex.lock();
226 impl->m_WorkingMutex.lock();
227 qCDebug(LOG_VariableController()) << tr("VariableController init END");
227 qCDebug(LOG_VariableController()) << tr("VariableController init END");
228 }
228 }
229
229
230 void VariableController::finalize()
230 void VariableController::finalize()
231 {
231 {
232 impl->m_WorkingMutex.unlock();
232 impl->m_WorkingMutex.unlock();
233 }
233 }
234
234
235 void VariableController::waitForFinish()
235 void VariableController::waitForFinish()
236 {
236 {
237 QMutexLocker locker{&impl->m_WorkingMutex};
237 QMutexLocker locker{&impl->m_WorkingMutex};
238 }
238 }
General Comments 0
You need to be logged in to leave comments. Login now