Skip to content
Permalink
Browse files

Fix stuck tasks when proxied task using a proxy progress task

completes before the proxy task has been started by task manager

Fixes #21589, fixes #19761
  • Loading branch information
nyalldawson committed Apr 1, 2019
1 parent 7674e16 commit b28227fa7f946e0c0ccba1b588a8ac47fef0c85f
Showing with 83 additions and 2 deletions.
  1. +7 −1 src/core/qgsproxyprogresstask.cpp
  2. +1 −0 src/core/qgsproxyprogresstask.h
  3. +75 −1 tests/src/core/testqgstaskmanager.cpp
@@ -25,14 +25,20 @@ QgsProxyProgressTask::QgsProxyProgressTask( const QString &description )

void QgsProxyProgressTask::finalize( bool result )
{
QMutexLocker lock( &mNotFinishedMutex );
mAlreadyFinished = true;

mResult = result;
mNotFinishedWaitCondition.wakeAll();
}

bool QgsProxyProgressTask::run()
{
mNotFinishedMutex.lock();
mNotFinishedWaitCondition.wait( &mNotFinishedMutex );
if ( !mAlreadyFinished )
{
mNotFinishedWaitCondition.wait( &mNotFinishedMutex );
}
mNotFinishedMutex.unlock();

return mResult;
@@ -64,6 +64,7 @@ class CORE_EXPORT QgsProxyProgressTask : public QgsTask

QWaitCondition mNotFinishedWaitCondition;
QMutex mNotFinishedMutex;
bool mAlreadyFinished = false;
bool mResult = true;

};
@@ -19,6 +19,7 @@
#include "qgsproject.h"
#include "qgsvectorlayer.h"
#include "qgsapplication.h"
#include "qgsproxyprogresstask.h"
#include <QObject>
#include "qgstest.h"

@@ -270,6 +271,9 @@ class TestQgsTaskManager : public QObject
void managerWithSubTasks2();
void managerWithSubTasks3();
void cancelBeforeStart();
void proxyTask();
void proxyTask2();
void scopedProxyTask();
};

void TestQgsTaskManager::initTestCase()
@@ -731,7 +735,7 @@ void TestQgsTaskManager::taskId()

void TestQgsTaskManager::waitForFinished()
{
if ( QgsTest::isTravis() )
if ( !QgsTest::runFlakyTests() )
QSKIP( "This test is disabled on Travis CI environment" );

QgsTaskManager manager;
@@ -1374,5 +1378,75 @@ void TestQgsTaskManager::cancelBeforeStart()
flushEvents();
}

void TestQgsTaskManager::proxyTask()
{
if ( !QgsTest::runFlakyTests() )
QSKIP( "This test is disabled on Travis CI environment" );

QgsProxyProgressTask *proxyTask = new QgsProxyProgressTask( QString() );

// finalize before task gets a chance to start
QgsTaskManager manager;
proxyTask->finalize( false );
QPointer< QgsTask > p( proxyTask );

manager.addTask( proxyTask );

// should all be ok, no deadlock...
while ( p )
{
QCoreApplication::processEvents();
}
flushEvents();
}

void TestQgsTaskManager::proxyTask2()
{
if ( !QgsTest::runFlakyTests() )
QSKIP( "This test is disabled on Travis CI environment" );

QgsProxyProgressTask *proxyTask = new QgsProxyProgressTask( QString() );

// finalize before task gets a chance to start
QgsTaskManager manager;
QPointer< QgsTask > p( proxyTask );
manager.addTask( proxyTask );

// should all be ok, no deadlock...
while ( proxyTask->status() != QgsTask::Running )
{
QCoreApplication::processEvents();
}
proxyTask->finalize( false );
while ( p )
{
QCoreApplication::processEvents();
}

flushEvents();
}

void TestQgsTaskManager::scopedProxyTask()
{
if ( !QgsTest::runFlakyTests() )
QSKIP( "This test is disabled on Travis CI environment" );

{
// task finishes before it can start
QgsScopedProxyProgressTask task{ QString() };
}

// should all be ok, no deadlock...
while ( QgsApplication::taskManager()->countActiveTasks() == 0 )
{
QCoreApplication::processEvents();
}
while ( QgsApplication::taskManager()->countActiveTasks() > 0 )
{
QCoreApplication::processEvents();
}
flushEvents();
}

QGSTEST_MAIN( TestQgsTaskManager )
#include "testqgstaskmanager.moc"

0 comments on commit b28227f

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