##// END OF EJS Templates
Add thread protection on AbortDownload process
perrinel -
r423:3698da027722
parent child
Show More
@@ -4,6 +4,7
4 4 #include <QNetworkAccessManager>
5 5 #include <QNetworkReply>
6 6 #include <QNetworkRequest>
7 #include <QReadWriteLock>
7 8 #include <QThread>
8 9
9 10 #include <unordered_map>
@@ -14,8 +15,13 struct NetworkController::NetworkControllerPrivate {
14 15 explicit NetworkControllerPrivate(NetworkController *parent) : m_WorkingMutex{} {}
15 16 QMutex m_WorkingMutex;
16 17
18 QReadWriteLock m_Lock;
17 19 std::unordered_map<QNetworkReply *, QUuid> m_NetworkReplyToVariableId;
18 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 27 NetworkController::NetworkController(QObject *parent)
@@ -26,30 +32,50 NetworkController::NetworkController(QObject *parent)
26 32 void NetworkController::onProcessRequested(const QNetworkRequest &request, QUuid identifier,
27 33 std::function<void(QNetworkReply *, QUuid)> callback)
28 34 {
29 qCInfo(LOG_NetworkController()) << tr("NetworkController registered")
30 << QThread::currentThread();
31 35 auto reply = impl->m_AccessManager->get(request);
36 qCDebug(LOG_NetworkController()) << tr("NetworkController registered")
37 << QThread::currentThread() << reply;
32 38
33 39 // Store the couple reply id
40 impl->lockWrite();
34 41 impl->m_NetworkReplyToVariableId[reply] = identifier;
42 impl->unlock();
35 43
36 44 auto onReplyFinished = [reply, this, identifier, callback]() {
37 45
38 qCInfo(LOG_NetworkController()) << tr("NetworkController onReplyFinished")
39 << QThread::currentThread();
46 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyFinished")
47 << QThread::currentThread() << reply;
48 impl->lockRead();
40 49 auto it = impl->m_NetworkReplyToVariableId.find(reply);
50 impl->unlock();
41 51 if (it != impl->m_NetworkReplyToVariableId.cend()) {
52 impl->lockWrite();
53 impl->m_NetworkReplyToVariableId.erase(reply);
54 impl->unlock();
55 // Deletes reply
42 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 66 auto onReplyProgress = [reply, this](qint64 bytesRead, qint64 totalBytes) {
47 67
48 68 double progress = (bytesRead * 100.0) / totalBytes;
69 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress") << progress
70 << QThread::currentThread() << reply;
71 impl->lockRead();
49 72 auto it = impl->m_NetworkReplyToVariableId.find(reply);
73 impl->unlock();
50 74 if (it != impl->m_NetworkReplyToVariableId.cend()) {
51 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 99 void NetworkController::onReplyCanceled(QUuid identifier)
74 100 {
75 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 107 auto end = impl->m_NetworkReplyToVariableId.cend();
78 108 auto it = std::find_if(impl->m_NetworkReplyToVariableId.cbegin(), end, findReply);
109 impl->unlock();
79 110 if (it != end) {
80 111 it->first->abort();
81 112 }
113 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled END")
114 << QThread::currentThread();
82 115 }
83 116
84 117 void NetworkController::waitForFinish()
@@ -178,8 +178,8 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> vari
178 178 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
179 179 << QThread::currentThread()->objectName();
180 180
181 auto it = impl->m_VariableToIdentifier.find(variable);
182 if (it != impl->m_VariableToIdentifier.cend()) {
181 auto it = impl->m_VariableToIdentifierMap.find(variable);
182 if (it != impl->m_VariableToIdentifierMap.cend()) {
183 183 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
184 184 }
185 185 else {
General Comments 0
You need to be logged in to leave comments. Login now