Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix some crashes
  • Loading branch information
nyalldawson committed Dec 5, 2016
1 parent 55e9d32 commit f85d24e
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 3 deletions.
28 changes: 26 additions & 2 deletions src/core/qgstaskmanager.cpp
Expand Up @@ -108,6 +108,7 @@ QgsTaskManager *QgsTaskManager::instance()

QgsTaskManager::QgsTaskManager( QObject* parent )
: QObject( parent )
, mTaskMutex( new QMutex( QMutex::Recursive ) )
, mNextTaskId( 0 )
{
connect( QgsMapLayerRegistry::instance(), SIGNAL( layersWillBeRemoved( QStringList ) ),
Expand All @@ -120,15 +121,20 @@ QgsTaskManager::~QgsTaskManager()
cancelAll();

//then clean them up, including waiting for them to terminate
mTaskMutex->lock();
QMap< long, TaskInfo >::const_iterator it = mTasks.constBegin();
for ( ; it != mTasks.constEnd(); ++it )
{
cleanupAndDeleteTask( it.value().task );
}
mTaskMutex->unlock();

delete mTaskMutex;
}

long QgsTaskManager::addTask( QgsTask* task, const QgsTaskList& dependencies )
{
QMutexLocker ml( mTaskMutex );
mTasks.insert( mNextTaskId, task );

connect( task, SIGNAL( progressChanged( double ) ), this, SLOT( taskProgressChanged( double ) ) );
Expand All @@ -152,6 +158,7 @@ long QgsTaskManager::addTask( QgsTask* task, const QgsTaskList& dependencies )

bool QgsTaskManager::deleteTask( long id )
{
QMutexLocker ml( mTaskMutex );
QgsTask* task = mTasks.value( id ).task;
return deleteTask( task );
}
Expand All @@ -164,6 +171,7 @@ bool QgsTaskManager::deleteTask( QgsTask *task )
bool result = cleanupAndDeleteTask( task );

// remove from internal task list
QMutexLocker ml( mTaskMutex );
for ( QMap< long, TaskInfo >::iterator it = mTasks.begin(); it != mTasks.end(); )
{
if ( it.value().task == task )
Expand All @@ -177,11 +185,13 @@ bool QgsTaskManager::deleteTask( QgsTask *task )

QgsTask*QgsTaskManager::task( long id ) const
{
QMutexLocker ml( mTaskMutex );
return mTasks.value( id ).task;
}

QList<QgsTask*> QgsTaskManager::tasks() const
{
QMutexLocker ml( mTaskMutex );
QList< QgsTask* > list;
for ( QMap< long, TaskInfo >::const_iterator it = mTasks.constBegin(); it != mTasks.constEnd(); ++it )
{
Expand All @@ -195,19 +205,23 @@ long QgsTaskManager::taskId( QgsTask *task ) const
if ( !task )
return -1;

QMutexLocker ml( mTaskMutex );
QMap< long, TaskInfo >::const_iterator it = mTasks.constBegin();
for ( ; it != mTasks.constEnd(); ++it )
{
if ( it.value().task == task )
{
return it.key();
}
}
return -1;
}

void QgsTaskManager::cancelAll()
{
QMap< long, TaskInfo >::iterator it = mTasks.begin();
for ( ; it != mTasks.end(); ++it )
QMutexLocker ml( mTaskMutex );
QMap< long, TaskInfo >::const_iterator it = mTasks.constBegin();
for ( ; it != mTasks.constEnd(); ++it )
{
QgsTask* task = it.value().task;
if ( task->isActive() )
Expand All @@ -219,6 +233,8 @@ void QgsTaskManager::cancelAll()

bool QgsTaskManager::dependenciesSatisified( long taskId ) const
{
QMutexLocker ml( mTaskMutex );

if ( !mTaskDependencies.contains( taskId ) )
return true;

Expand All @@ -242,6 +258,8 @@ QSet<long> QgsTaskManager::dependencies( long taskId ) const

bool QgsTaskManager::resolveDependencies( long firstTaskId, long currentTaskId, QSet<long>& results ) const
{
QMutexLocker ml( mTaskMutex );

if ( !mTaskDependencies.contains( currentTaskId ) )
return true;

Expand Down Expand Up @@ -282,11 +300,13 @@ bool QgsTaskManager::hasCircularDependencies( long taskId ) const

void QgsTaskManager::setDependentLayers( long taskId, const QStringList& layerIds )
{
QMutexLocker ml( mTaskMutex );
mLayerDependencies.insert( taskId, layerIds );
}

QStringList QgsTaskManager::dependentLayers( long taskId ) const
{
QMutexLocker ml( mTaskMutex );
return mLayerDependencies.value( taskId, QStringList() );
}

Expand Down Expand Up @@ -323,6 +343,7 @@ void QgsTaskManager::taskStatusChanged( int status )

void QgsTaskManager::layersWillBeRemoved( const QStringList& layerIds )
{
QMutexLocker ml( mTaskMutex );
// scan through layers to be removed
Q_FOREACH ( const QString& layerId, layerIds )
{
Expand Down Expand Up @@ -371,6 +392,7 @@ bool QgsTaskManager::cleanupAndDeleteTask( QgsTask *task )

void QgsTaskManager::processQueue()
{
QMutexLocker ml( mTaskMutex );
for ( QMap< long, TaskInfo >::iterator it = mTasks.begin(); it != mTasks.end(); ++it )
{
QgsTask* task = it.value().task;
Expand All @@ -383,6 +405,8 @@ void QgsTaskManager::processQueue()

void QgsTaskManager::cancelDependentTasks( long taskId )
{
QMutexLocker ml( mTaskMutex );

QgsTask* cancelledTask = task( taskId );
for ( QMap< long, QgsTaskList >::iterator it = mTaskDependencies.begin(); it != mTaskDependencies.end(); ++it )
{
Expand Down
1 change: 1 addition & 0 deletions src/core/qgstaskmanager.h
Expand Up @@ -305,6 +305,7 @@ class CORE_EXPORT QgsTaskManager : public QObject
QFuture< void > future;
};

mutable QMutex* mTaskMutex;
QMap< long, TaskInfo > mTasks;
QMap< long, QgsTaskList > mTaskDependencies;
QMap< long, QStringList > mLayerDependencies;
Expand Down
5 changes: 4 additions & 1 deletion tests/src/core/testqgstaskmanager.cpp
Expand Up @@ -83,7 +83,7 @@ class TestQgsTaskManager : public QObject
void createInstance();
void addTask();
void deleteTask();
void taskTerminationBeforeDelete();
//void taskTerminationBeforeDelete();
void taskId();
void progressChanged();
void statusChanged();
Expand Down Expand Up @@ -259,6 +259,8 @@ void TestQgsTaskManager::deleteTask()
QCOMPARE( spy.last().at( 0 ).toLongLong(), 0LL );
}

#if 0
// we don't run this by default - the sendPostedEvents call is fragile
void TestQgsTaskManager::taskTerminationBeforeDelete()
{
//test that task is terminated by manager prior to delete
Expand All @@ -276,6 +278,7 @@ void TestQgsTaskManager::taskTerminationBeforeDelete()
delete manager;
QApplication::sendPostedEvents( nullptr, QEvent::DeferredDelete );
}
#endif

void TestQgsTaskManager::taskId()
{
Expand Down

0 comments on commit f85d24e

Please sign in to comment.