Merge remote-tracking branch 'origin/2.3'
authorOlivier Goffart <ogoffart@woboq.com>
Thu, 9 Mar 2017 08:54:14 +0000 (09:54 +0100)
committerOlivier Goffart <ogoffart@woboq.com>
Thu, 9 Mar 2017 08:54:14 +0000 (09:54 +0100)
 Conflicts:
src/libsync/owncloudpropagator.cpp

1  2 
src/libsync/owncloudpropagator.cpp
src/libsync/propagatedownload.cpp
test/testsyncengine.cpp

index dc5ab5a3ffc47bcdef13cec02305c276c8b504b1,e2c910213ffafa75358b77e3b14ec7671d4a0ccc..286cb34bccfdfc320e43eb45ccb0e34028e469e4
@@@ -670,110 -655,46 +670,112 @@@ void PropagatorCompositeJob::slotSubJob
  
      // Delete the job and remove it from our list of jobs.
      subJob->deleteLater();
 -    bool wasFirstJob = false;
 -    if (subJob == _firstJob.data()) {
 -        wasFirstJob = true;
 -        _firstJob.take();
 +    int i = _runningJobs.indexOf(subJob);
 +    ASSERT(i >= 0);
 +    _runningJobs.remove(i);
 +
 +    if (status == SyncFileItem::FatalError
 +        || status == SyncFileItem::NormalError
 +        || status == SyncFileItem::SoftError) {
 +        _hasError = status;
 +    }
 +
 +    if (_jobsToDo.isEmpty() && _tasksToDo.isEmpty() && _runningJobs.isEmpty()) {
 +        finalize();
      } else {
 -        int i = _subJobs.indexOf(subJob);
 -        // Shouldn't happen but could be -1 if finished was emitted twice for a job.
 -        ASSERT(i >= 0);
 -        if (i >= 0)
 -            _subJobs.remove(i);
 +        propagator()->scheduleNextJob();
 +    }
 +}
 +
 +void PropagatorCompositeJob::finalize()
 +{
 +    // The propagator will do parallel scheduling and this could be posted
 +    // multiple times on the event loop, ignore the duplicate calls.
 +    if (_state == Finished)
 +        return;
 +
 +    _state = Finished;
 +    emit finished(_hasError == SyncFileItem::NoStatus ?  SyncFileItem::Success : _hasError);
 +}
 +
 +qint64 PropagatorCompositeJob::committedDiskSpace() const
 +{
 +    qint64 needed = 0;
 +    foreach (PropagatorJob* job, _runningJobs) {
 +        needed += job->committedDiskSpace();
 +    }
 +    return needed;
 +}
 +
 +// ================================================================================
 +
 +PropagateDirectory::PropagateDirectory(OwncloudPropagator *propagator, const SyncFileItemPtr &item)
 +    : PropagatorJob(propagator)
 +    , _item(item)
 +    , _firstJob(propagator->createJob(item))
 +    , _subJobs(propagator)
 +{
 +    if (_firstJob) {
 +        connect(_firstJob.data(), SIGNAL(finished(SyncFileItem::Status)), this, SLOT(slotFirstJobFinished(SyncFileItem::Status)));
 +    }
 +    connect(&_subJobs, SIGNAL(finished(SyncFileItem::Status)), this, SLOT(slotSubJobsFinished(SyncFileItem::Status)));
 +}
 +
 +PropagatorJob::JobParallelism PropagateDirectory::parallelism()
 +{
 +    // If any of the non-finished sub jobs is not parallel, we have to wait
 +    if (_firstJob && _firstJob->parallelism() != FullParallelism) {
 +        return WaitForFinished;
 +    }
 +    if (_subJobs.parallelism() != FullParallelism) {
 +        return WaitForFinished;
 +    }
 +    return FullParallelism;
 +}
 +
 +
 +bool PropagateDirectory::scheduleSelfOrChild()
 +{
 +    if (_state == Finished) {
 +        return false;
 +    }
 +
 +    if (_state == NotYetStarted) {
 +        _state = Running;
      }
  
 -    if (status == SyncFileItem::FatalError ||
 -            (wasFirstJob && status != SyncFileItem::Success && status != SyncFileItem::Restoration)) {
 +    if (_firstJob && _firstJob->_state == NotYetStarted) {
 +        return _firstJob->scheduleSelfOrChild();
 +    }
 +
 +    if (_firstJob && _firstJob->_state == Running) {
 +        // Don't schedule any more job until this is done.
 +        return false;
 +    }
 +
 +    return _subJobs.scheduleSelfOrChild();
 +
 +}
 +
 +void PropagateDirectory::slotFirstJobFinished(SyncFileItem::Status status)
 +{
 +    _firstJob.take()->deleteLater();
 +
 +    if (status != SyncFileItem::Success && status != SyncFileItem::Restoration) {
-         abort();
-         _state = Finished;
-         emit finished(status);
+         if (_state != Finished) {
+             abort();
+             _state = Finished;
+             emit finished(status);
+         }
          return;
 -    } else if (status == SyncFileItem::NormalError || status == SyncFileItem::SoftError) {
 -        _hasError = status;
      }
  
 -    // We finished processing all the jobs
 -    // check if we finished
 -    if (!_firstJob && _subJobs.isEmpty()) {
 -        finalize();
 -    } else {
 -        emit ready();
 -    }
 +    propagator()->scheduleNextJob();
  }
  
 -void PropagateDirectory::finalize()
 +void PropagateDirectory::slotSubJobsFinished(SyncFileItem::Status status)
  {
 -    if (_state == Finished)
 -        return;
 -
 -    bool ok = true;
 -    if (!_item->isEmpty() && _hasError == SyncFileItem::NoStatus) {
 +    if (!_item->isEmpty() && status == SyncFileItem::Success) {
          if( !_item->_renameTarget.isEmpty() ) {
              if(_item->_instruction == CSYNC_INSTRUCTION_RENAME
                      && _item->_originalFile != _item->_renameTarget) {
Simple merge
Simple merge