From: Olivier Goffart Date: Thu, 9 Mar 2017 08:54:14 +0000 (+0100) Subject: Merge remote-tracking branch 'origin/2.3' X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~794 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=0e8f0481d434272ad593f14e37db1774cf568c47;p=nextcloud-desktop.git Merge remote-tracking branch 'origin/2.3' Conflicts: src/libsync/owncloudpropagator.cpp --- 0e8f0481d434272ad593f14e37db1774cf568c47 diff --cc src/libsync/owncloudpropagator.cpp index dc5ab5a3f,e2c910213..286cb34bc --- a/src/libsync/owncloudpropagator.cpp +++ b/src/libsync/owncloudpropagator.cpp @@@ -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) {