Преглед на файлове

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.
Jocelyn Turcotte преди 9 години
родител
ревизия
793a994ce6
променени са 2 файла, в които са добавени 12 реда и са изтрити 8 реда
  1. 8 6
      src/libsync/owncloudpropagator.cpp
  2. 4 2
      src/libsync/owncloudpropagator.h

+ 8 - 6
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;
     }
 

+ 4 - 2
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