From 793a994ce69c05d54c0a1a75f4bd3ca12dc41f51 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Fri, 17 Feb 2017 12:57:24 +0100 Subject: [PATCH] Don't abort propagation job abortions synchronously from finished This leads to crashes since we changed the connection to the parent jobs not to be queued anymore. We don't really need to bubble up the finished state through parents in that case, and it would also mean that we'd recurse all the way through leaves as we go up to each parent. So just call abort directly on the OwncloudPropagator and make sure the abortion call is posted to the event loop. --- src/libsync/owncloudpropagator.cpp | 14 ++++++++------ src/libsync/owncloudpropagator.h | 6 ++++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/libsync/owncloudpropagator.cpp b/src/libsync/owncloudpropagator.cpp index 40e3c6786..dc5ab5a3f 100644 --- a/src/libsync/owncloudpropagator.cpp +++ b/src/libsync/owncloudpropagator.cpp @@ -171,6 +171,11 @@ void PropagateItemJob::done(SyncFileItem::Status status, const QString &errorStr emit propagator()->itemCompleted(_item); emit finished(status); + + if (status == SyncFileItem::FatalError) { + // Abort all remaining jobs. + propagator()->abort(); + } } /** @@ -669,12 +674,9 @@ void PropagatorCompositeJob::slotSubJobFinished(SyncFileItem::Status status) ASSERT(i >= 0); _runningJobs.remove(i); - if (status == SyncFileItem::FatalError) { - abort(); - _state = Finished; - emit finished(status); - return; - } else if (status == SyncFileItem::NormalError || status == SyncFileItem::SoftError) { + if (status == SyncFileItem::FatalError + || status == SyncFileItem::NormalError + || status == SyncFileItem::SoftError) { _hasError = status; } diff --git a/src/libsync/owncloudpropagator.h b/src/libsync/owncloudpropagator.h index 0ef06ee70..ccb7e6d3c 100644 --- a/src/libsync/owncloudpropagator.h +++ b/src/libsync/owncloudpropagator.h @@ -331,9 +331,11 @@ public: void abort() { _abortRequested.fetchAndStoreOrdered(true); if (_rootJob) { - _rootJob->abort(); + // We're possibly already in an item's finished stack + QMetaObject::invokeMethod(_rootJob.data(), "abort", Qt::QueuedConnection); } - emitFinished(SyncFileItem::NormalError); + // abort() of all jobs will likely have already resulted in finished being emitted, but just in case. + QMetaObject::invokeMethod(this, "emitFinished", Qt::QueuedConnection, Q_ARG(SyncFileItem::Status, SyncFileItem::NormalError)); } // timeout in seconds -- 2.30.2