Skip to content

Commit 82ebf8a

Browse files
committedDec 20, 2018
Use two wait conditions as per producer/consumer solution
1 parent a048306 commit 82ebf8a

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed
 

‎src/core/qgsblockingnetworkrequest.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,22 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBl
9595
request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, forceRefresh ? QNetworkRequest::AlwaysNetwork : QNetworkRequest::PreferCache );
9696
request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );
9797

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;
99105
QMutex waitConditionMutex;
106+
100107
bool threadFinished = false;
101108
bool success = false;
102109

103110
if ( mFeedback )
104111
connect( mFeedback, &QgsFeedback::canceled, this, &QgsBlockingNetworkRequest::abort );
105112

106-
std::function<void()> downloaderFunction = [ this, request, &waitConditionMutex, &waitCondition, &threadFinished, &success ]()
113+
std::function<void()> downloaderFunction = [ this, request, &waitConditionMutex, &authRequestBufferNotEmpty, &authRequestBufferNotFull, &threadFinished, &success ]()
107114
{
108115
if ( QThread::currentThread() != QgsApplication::instance()->thread() )
109116
QgsNetworkAccessManager::instance( Qt::DirectConnection );
@@ -130,7 +137,7 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBl
130137
mErrorCode = NetworkError;
131138
mErrorMessage = errorMessageFailedAuth();
132139
QgsMessageLog::logMessage( mErrorMessage, tr( "Network" ) );
133-
waitCondition.wakeAll();
140+
authRequestBufferNotEmpty.wakeAll();
134141
success = false;
135142
}
136143
else
@@ -141,14 +148,16 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBl
141148
connect( mReply, &QNetworkReply::finished, this, &QgsBlockingNetworkRequest::replyFinished, Qt::DirectConnection );
142149
connect( mReply, &QNetworkReply::downloadProgress, this, &QgsBlockingNetworkRequest::replyProgress, Qt::DirectConnection );
143150

144-
auto resumeMainThread = [&waitConditionMutex, &waitCondition]()
151+
auto resumeMainThread = [&waitConditionMutex, &authRequestBufferNotEmpty, &authRequestBufferNotFull ]()
145152
{
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
146155
waitConditionMutex.lock();
147-
waitCondition.wakeAll();
156+
authRequestBufferNotFull.wait( &waitConditionMutex );
148157
waitConditionMutex.unlock();
149158

150159
waitConditionMutex.lock();
151-
waitCondition.wait( &waitConditionMutex );
160+
authRequestBufferNotEmpty.wakeAll();
152161
waitConditionMutex.unlock();
153162
};
154163

@@ -164,7 +173,7 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBl
164173
}
165174
waitConditionMutex.lock();
166175
threadFinished = true;
167-
waitCondition.wakeAll();
176+
authRequestBufferNotEmpty.wakeAll();
168177
waitConditionMutex.unlock();
169178
};
170179

@@ -181,10 +190,10 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBl
181190
waitConditionMutex.unlock();
182191
break;
183192
}
184-
waitCondition.wait( &waitConditionMutex );
193+
authRequestBufferNotEmpty.wait( &waitConditionMutex );
185194

186195
// 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".
188197
// The processEvents() call gives the auth manager the chance to show a dialog and
189198
// once done with that, we can wake the downloaderThread again and continue the download.
190199
if ( !threadFinished )
@@ -193,7 +202,7 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBl
193202

194203
QgsApplication::instance()->processEvents();
195204
waitConditionMutex.lock();
196-
waitCondition.wakeAll();
205+
authRequestBufferNotFull.wakeAll();
197206
waitConditionMutex.unlock();
198207
}
199208
else

0 commit comments

Comments
 (0)
Please sign in to comment.