Skip to content
Permalink
Browse files

[wfs] Fix some race conditions

  • Loading branch information
nyalldawson committed Sep 4, 2018
1 parent 0b4694f commit 2041cad0c0ce38bcecfa0f4eb203a94ded207886
Showing with 26 additions and 20 deletions.
  1. +23 −11 src/providers/wfs/qgswfsrequest.cpp
  2. +3 −9 src/providers/wfs/qgswfsrequest.h
@@ -130,13 +130,15 @@ bool QgsWfsRequest::sendGET( const QUrl &url, bool synchronous, bool forceRefres

QWaitCondition waitCondition;
QMutex waitConditionMutex;
bool threadFinished = false;
bool success = false;

std::function<bool()> downloaderFunction = [ this, request, synchronous, &waitConditionMutex, &waitCondition ]()
std::function<void()> downloaderFunction = [ this, request, synchronous, &waitConditionMutex, &waitCondition, &threadFinished, &success ]()
{
if ( QThread::currentThread() != QgsApplication::instance()->thread() )
QgsNetworkAccessManager::instance( Qt::DirectConnection );

bool success = true;
success = true;
mReply = QgsNetworkAccessManager::instance()->get( request );

mReply->setReadBufferSize( READ_BUFFER_SIZE_HINT );
@@ -180,41 +182,51 @@ bool QgsWfsRequest::sendGET( const QUrl &url, bool synchronous, bool forceRefres
loop.exec();
}
}
waitConditionMutex.lock();
threadFinished = true;
waitCondition.wakeAll();
return success;
waitConditionMutex.unlock();
};

bool success;

if ( synchronous && QThread::currentThread() == QApplication::instance()->thread() )
{
std::unique_ptr<DownloaderThread> downloaderThread = qgis::make_unique<DownloaderThread>( downloaderFunction );
downloaderThread->start();

while ( !downloaderThread->isFinished() )
while ( true )
{
waitConditionMutex.lock();
if ( threadFinished )
{
waitConditionMutex.unlock();
break;
}
waitCondition.wait( &waitConditionMutex );
waitConditionMutex.unlock();

// If the downloader thread wakes us (the main thread) up and is not yet finished
// he needs the authentication to run.
// The processEvents() call gives the auth manager the chance to show a dialog and
// once done with that, we can wake the downloaderThread again and continue the download.
if ( !downloaderThread->isFinished() )
if ( !threadFinished )
{
waitConditionMutex.unlock();

QgsApplication::instance()->processEvents();
waitConditionMutex.lock();
waitCondition.wakeAll();
waitConditionMutex.unlock();
}
else
{
waitConditionMutex.unlock();
}
}

success = downloaderThread->success();
// wait for thread to gracefully exit
downloaderThread->wait();
}
else
{
success = downloaderFunction();
downloaderFunction();
}
return success && mErrorMessage.isEmpty();
}
@@ -124,25 +124,19 @@ class DownloaderThread : public QThread
Q_OBJECT

public:
DownloaderThread( std::function<bool()> function, QObject *parent = nullptr )
DownloaderThread( std::function<void()> function, QObject *parent = nullptr )
: QThread( parent )
, mFunction( function )
{
}

void run() override
{
mSuccess = mFunction();
}

bool success() const
{
return mSuccess;
mFunction();
}

private:
std::function<bool()> mFunction;
bool mSuccess = false;
std::function<void()> mFunction;
};

#endif // QGSWFSREQUEST_H

0 comments on commit 2041cad

Please sign in to comment.
You can’t perform that action at this time.