Skip to content

Commit

Permalink
Fix some authentication interaction threading issues
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Jun 14, 2018
1 parent 44e8f60 commit 410d855
Showing 1 changed file with 28 additions and 9 deletions.
37 changes: 28 additions & 9 deletions src/providers/wfs/qgswfsrequest.cpp
Expand Up @@ -128,10 +128,13 @@ bool QgsWfsRequest::sendGET( const QUrl &url, bool synchronous, bool forceRefres
request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );
}

QWaitCondition waitCondition;
QWaitCondition mainThreadWaitCondition;
QMutex mainThreadMutex;

QMutex mutex;
std::function<bool()> downloaderFunction = [ this, request, synchronous, &waitCondition ]()
QWaitCondition downloaderThreadWaitCondition;
QMutex downloaderThreadMutex;

std::function<bool()> downloaderFunction = [ this, request, synchronous, &mainThreadMutex, &mainThreadWaitCondition, &downloaderThreadMutex, &downloaderThreadWaitCondition ]()
{
if ( QThread::currentThread() != QgsApplication::instance()->thread() )
QgsNetworkAccessManager::instance( Qt::DirectConnection );
Expand All @@ -145,26 +148,36 @@ bool QgsWfsRequest::sendGET( const QUrl &url, bool synchronous, bool forceRefres
mErrorCode = QgsWfsRequest::NetworkError;
mErrorMessage = errorMessageFailedAuth();
QgsMessageLog::logMessage( mErrorMessage, tr( "WFS" ) );
waitCondition.wakeAll();
mainThreadWaitCondition.wakeAll();
success = false;
}
else
{
// We are able to use direct connection here, because we
// * either run on the thread mReply lives in, so DirectConnection is standard and safe anyway (if it is not the main thread)
// * either run on the thread mReply lives in, so DirectConnection is standard and safe anyway
// * or the owner thread of mReply is currently not doing anything because it's blocked in future.waitForFinished() (if it is the main thread)
connect( mReply, &QNetworkReply::finished, this, &QgsWfsRequest::replyFinished, Qt::DirectConnection );
connect( mReply, &QNetworkReply::downloadProgress, this, &QgsWfsRequest::replyProgress, Qt::DirectConnection );
connect( QgsNetworkAccessManager::instance(), &QgsNetworkAccessManager::authenticationRequired, this, [&waitCondition]() { waitCondition.wakeAll(); } );

if ( synchronous )
{
connect( QgsNetworkAccessManager::instance(), &QgsNetworkAccessManager::authenticationRequired, this, [&mainThreadMutex, &mainThreadWaitCondition, &downloaderThreadMutex, &downloaderThreadWaitCondition]()
{
mainThreadMutex.lock();
mainThreadWaitCondition.wakeAll();
mainThreadMutex.unlock();

downloaderThreadMutex.lock();
downloaderThreadWaitCondition.wait( &downloaderThreadMutex );
downloaderThreadMutex.unlock();
}, Qt::DirectConnection
);
QEventLoop loop;
connect( this, &QgsWfsRequest::downloadFinished, &loop, &QEventLoop::quit, Qt::DirectConnection );
loop.exec();
}
}
waitCondition.wakeAll();
mainThreadWaitCondition.wakeAll();
return success;
};

Expand All @@ -176,9 +189,16 @@ bool QgsWfsRequest::sendGET( const QUrl &url, bool synchronous, bool forceRefres
downloaderThread->start();
while ( !downloaderThread->isFinished() )
{
waitCondition.wait( &mutex );
mainThreadMutex.lock();
mainThreadWaitCondition.wait( &mainThreadMutex );
mainThreadMutex.unlock();
if ( !downloaderThread->isFinished() )
{
QgsApplication::instance()->processEvents();
downloaderThreadMutex.lock();
downloaderThreadWaitCondition.wakeAll();
downloaderThreadMutex.unlock();
}
}

success = downloaderThread->success();
Expand All @@ -187,7 +207,6 @@ bool QgsWfsRequest::sendGET( const QUrl &url, bool synchronous, bool forceRefres
{
success = downloaderFunction();
}
mutex.unlock();
return success && mErrorMessage.isEmpty();
}

Expand Down

0 comments on commit 410d855

Please sign in to comment.