Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHannah von Reth <hannah.vonreth@owncloud.com>2021-11-19 17:31:11 +0300
committerHannah von Reth <vonreth@kde.org>2021-11-22 14:17:56 +0300
commit07aaba8f880e717039e22850d24d4c59e9cfb06d (patch)
treee21639ba7129d78c2ccfa648510b9fdff5c1e959 /src/libsync
parent842e48d1b31cca782c78b66702bd27d38ba62110 (diff)
Fix crash in PropagateRemoteMkdir
Fixes: #9170
Diffstat (limited to 'src/libsync')
-rw-r--r--src/libsync/propagateremotemkdir.cpp84
-rw-r--r--src/libsync/propagateremotemkdir.h6
2 files changed, 43 insertions, 47 deletions
diff --git a/src/libsync/propagateremotemkdir.cpp b/src/libsync/propagateremotemkdir.cpp
index 199eba652..a1d951c57 100644
--- a/src/libsync/propagateremotemkdir.cpp
+++ b/src/libsync/propagateremotemkdir.cpp
@@ -22,8 +22,11 @@
#include <QFile>
#include <QLoggingCategory>
#include <QtConcurrent>
+
+using namespace std::chrono_literals;
+
namespace {
-auto UpdateMetaDataRetyTimeOut = std::chrono::seconds(30);
+constexpr auto UpdateMetaDataRetyTimeOut = 30s;
}
namespace OCC {
@@ -130,13 +133,12 @@ void PropagateRemoteMkdir::success()
{
// Never save the etag on first mkdir.
// Only fully propagated directories should have the etag set.
- auto itemCopy = *_item;
- itemCopy._etag.clear();
+ auto itemCopy = SyncFileItemPtr::create(*_item);
+ itemCopy->_etag.clear();
// save the file id already so we can detect rename or remove
// also convert to a placeholder for the proper behaviour of the file
- Q_ASSERT(thread() == qApp->thread());
- const auto result = propagator()->updateMetadata(itemCopy);
+ const auto result = propagator()->updateMetadata(*itemCopy);
if (!result) {
done(SyncFileItem::FatalError, tr("Error writing metadata to the database: %1").arg(result.error()));
return;
@@ -148,48 +150,7 @@ void PropagateRemoteMkdir::success()
// in case the file lock is active.
// Retry the conversion for UpdateMetaDataRetyTimeOut
// TODO: make update updateMetadata async in general
-
- // QtConcurrent does not support moves
- // use shared_ptr to manage the Result object
- using resultType = decltype(result);
- using resultTypePtr = decltype(std::shared_ptr<resultType>());
-
- auto *watcher = new QFutureWatcher<resultTypePtr>(this);
- connect(watcher, &QFutureWatcherBase::finished, this, [watcher, this] {
- const auto *result = watcher->result().get();
- if (*result) {
- switch (result->get()) {
- case Vfs::ConvertToPlaceholderResult::Ok:
- done(SyncFileItem::Success);
- return;
- case Vfs::ConvertToPlaceholderResult::Locked:
- done(SyncFileItem::SoftError, tr("Setting file status failed due to file lock"));
- return;
- case Vfs::ConvertToPlaceholderResult::Error:
- Q_UNREACHABLE();
- }
- }
- done(SyncFileItem::FatalError, result->error());
- });
-
- watcher->setFuture(QtConcurrent::run([p = propagator(), itemCopy] {
- // Try to update the meta data with a 30s timeout
- const auto start = std::chrono::steady_clock::now();
- while ((std::chrono::steady_clock::now() - start) < UpdateMetaDataRetyTimeOut) {
- QThread::sleep(1);
- auto result = std::make_shared<resultType>(p->updateMetadata(itemCopy));
- if (*result) {
- if (result->get() == Vfs::ConvertToPlaceholderResult::Locked) {
- continue;
- } else {
- return result;
- }
- } else {
- return result;
- }
- }
- return std::make_shared<resultType>(Vfs::ConvertToPlaceholderResult::Locked);
- }));
+ retryUpdateMetadata(std::chrono::steady_clock::now(), itemCopy);
return;
}
#else
@@ -197,4 +158,33 @@ void PropagateRemoteMkdir::success()
#endif
done(SyncFileItem::Success);
}
+
+#ifdef Q_OS_WIN
+void PropagateRemoteMkdir::retryUpdateMetadata(std::chrono::steady_clock::time_point start, SyncFileItemPtr item)
+{
+ // Try to update the meta data with a 30s timeout
+ if ((std::chrono::steady_clock::now() - start) < UpdateMetaDataRetyTimeOut) {
+ auto result = propagator()->updateMetadata(*item);
+ if (result) {
+ switch (*result) {
+ case Vfs::ConvertToPlaceholderResult::Ok:
+ done(SyncFileItem::Success);
+ return;
+ case Vfs::ConvertToPlaceholderResult::Locked:
+ // retry in 1s
+ QTimer::singleShot(1s, this, [start, item, this] {
+ retryUpdateMetadata(start, item);
+ });
+ return;
+ case Vfs::ConvertToPlaceholderResult::Error:
+ Q_UNREACHABLE();
+ }
+ } else {
+ done(SyncFileItem::FatalError, result.error());
+ return;
+ }
+ }
+ done(SyncFileItem::SoftError, tr("Setting file status failed due to file lock"));
+};
+#endif
}
diff --git a/src/libsync/propagateremotemkdir.h b/src/libsync/propagateremotemkdir.h
index d11681950..c75be43e5 100644
--- a/src/libsync/propagateremotemkdir.h
+++ b/src/libsync/propagateremotemkdir.h
@@ -52,5 +52,11 @@ private slots:
void slotStartMkcolJob();
void slotMkcolJobFinished();
void success();
+
+private:
+#ifdef Q_OS_WIN
+ void retryUpdateMetadata(std::chrono::steady_clock::time_point start, SyncFileItemPtr item);
+
+#endif
};
}