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 ); request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );
} }


QWaitCondition waitCondition; QWaitCondition mainThreadWaitCondition;
QMutex mainThreadMutex;


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

std::function<bool()> downloaderFunction = [ this, request, synchronous, &mainThreadMutex, &mainThreadWaitCondition, &downloaderThreadMutex, &downloaderThreadWaitCondition ]()
{ {
if ( QThread::currentThread() != QgsApplication::instance()->thread() ) if ( QThread::currentThread() != QgsApplication::instance()->thread() )
QgsNetworkAccessManager::instance( Qt::DirectConnection ); QgsNetworkAccessManager::instance( Qt::DirectConnection );
Expand All @@ -145,26 +148,36 @@ bool QgsWfsRequest::sendGET( const QUrl &url, bool synchronous, bool forceRefres
mErrorCode = QgsWfsRequest::NetworkError; mErrorCode = QgsWfsRequest::NetworkError;
mErrorMessage = errorMessageFailedAuth(); mErrorMessage = errorMessageFailedAuth();
QgsMessageLog::logMessage( mErrorMessage, tr( "WFS" ) ); QgsMessageLog::logMessage( mErrorMessage, tr( "WFS" ) );
waitCondition.wakeAll(); mainThreadWaitCondition.wakeAll();
success = false; success = false;
} }
else else
{ {
// We are able to use direct connection here, because we // 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) // * 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::finished, this, &QgsWfsRequest::replyFinished, Qt::DirectConnection );
connect( mReply, &QNetworkReply::downloadProgress, this, &QgsWfsRequest::replyProgress, Qt::DirectConnection ); connect( mReply, &QNetworkReply::downloadProgress, this, &QgsWfsRequest::replyProgress, Qt::DirectConnection );
connect( QgsNetworkAccessManager::instance(), &QgsNetworkAccessManager::authenticationRequired, this, [&waitCondition]() { waitCondition.wakeAll(); } );


if ( synchronous ) 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; QEventLoop loop;
connect( this, &QgsWfsRequest::downloadFinished, &loop, &QEventLoop::quit, Qt::DirectConnection ); connect( this, &QgsWfsRequest::downloadFinished, &loop, &QEventLoop::quit, Qt::DirectConnection );
loop.exec(); loop.exec();
} }
} }
waitCondition.wakeAll(); mainThreadWaitCondition.wakeAll();
return success; return success;
}; };


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


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


Expand Down

0 comments on commit 410d855

Please sign in to comment.