@@ -95,15 +95,22 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBl
95
95
request.setAttribute ( QNetworkRequest::CacheLoadControlAttribute, forceRefresh ? QNetworkRequest::AlwaysNetwork : QNetworkRequest::PreferCache );
96
96
request.setAttribute ( QNetworkRequest::CacheSaveControlAttribute, true );
97
97
98
- QWaitCondition waitCondition;
98
+ // QWaitCondition based producer/consumer problem
99
+ // taken from http://doc.qt.io/qt-5/qtcore-threads-waitconditions-example.html
100
+ // in this case the buffer has size 1 and potentially contains authentication requests
101
+ // from the producer (downloader thread), which the consumer (main thread) needs to
102
+ // handle
103
+ QWaitCondition authRequestBufferNotEmpty;
104
+ QWaitCondition authRequestBufferNotFull;
99
105
QMutex waitConditionMutex;
106
+
100
107
bool threadFinished = false ;
101
108
bool success = false ;
102
109
103
110
if ( mFeedback )
104
111
connect ( mFeedback , &QgsFeedback::canceled, this , &QgsBlockingNetworkRequest::abort );
105
112
106
- std::function<void ()> downloaderFunction = [ this , request, &waitConditionMutex, &waitCondition , &threadFinished, &success ]()
113
+ std::function<void ()> downloaderFunction = [ this , request, &waitConditionMutex, &authRequestBufferNotEmpty, &authRequestBufferNotFull , &threadFinished, &success ]()
107
114
{
108
115
if ( QThread::currentThread () != QgsApplication::instance ()->thread () )
109
116
QgsNetworkAccessManager::instance ( Qt::DirectConnection );
@@ -130,7 +137,7 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBl
130
137
mErrorCode = NetworkError;
131
138
mErrorMessage = errorMessageFailedAuth ();
132
139
QgsMessageLog::logMessage ( mErrorMessage , tr ( " Network" ) );
133
- waitCondition .wakeAll ();
140
+ authRequestBufferNotEmpty .wakeAll ();
134
141
success = false ;
135
142
}
136
143
else
@@ -141,14 +148,16 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBl
141
148
connect ( mReply , &QNetworkReply::finished, this , &QgsBlockingNetworkRequest::replyFinished, Qt::DirectConnection );
142
149
connect ( mReply , &QNetworkReply::downloadProgress, this , &QgsBlockingNetworkRequest::replyProgress, Qt::DirectConnection );
143
150
144
- auto resumeMainThread = [&waitConditionMutex, &waitCondition ]()
151
+ auto resumeMainThread = [&waitConditionMutex, &authRequestBufferNotEmpty, &authRequestBufferNotFull ]()
145
152
{
153
+ // when this method is called we have "produced" a single authentication request -- so the buffer is now full
154
+ // and it's time for the "consumer" (main thread) to do its part
146
155
waitConditionMutex.lock ();
147
- waitCondition. wakeAll ( );
156
+ authRequestBufferNotFull. wait ( &waitConditionMutex );
148
157
waitConditionMutex.unlock ();
149
158
150
159
waitConditionMutex.lock ();
151
- waitCondition. wait ( &waitConditionMutex );
160
+ authRequestBufferNotEmpty. wakeAll ( );
152
161
waitConditionMutex.unlock ();
153
162
};
154
163
@@ -164,7 +173,7 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBl
164
173
}
165
174
waitConditionMutex.lock ();
166
175
threadFinished = true ;
167
- waitCondition .wakeAll ();
176
+ authRequestBufferNotEmpty .wakeAll ();
168
177
waitConditionMutex.unlock ();
169
178
};
170
179
@@ -181,10 +190,10 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBl
181
190
waitConditionMutex.unlock ();
182
191
break ;
183
192
}
184
- waitCondition .wait ( &waitConditionMutex );
193
+ authRequestBufferNotEmpty .wait ( &waitConditionMutex );
185
194
186
195
// If the downloader thread wakes us (the main thread) up and is not yet finished
187
- // he needs the authentication to run .
196
+ // then it has "produced" an authentication request which we need to now "consume" .
188
197
// The processEvents() call gives the auth manager the chance to show a dialog and
189
198
// once done with that, we can wake the downloaderThread again and continue the download.
190
199
if ( !threadFinished )
@@ -193,7 +202,7 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBl
193
202
194
203
QgsApplication::instance ()->processEvents ();
195
204
waitConditionMutex.lock ();
196
- waitCondition .wakeAll ();
205
+ authRequestBufferNotFull .wakeAll ();
197
206
waitConditionMutex.unlock ();
198
207
}
199
208
else
0 commit comments