avoid deadlock: cancel hydration requests coming from itself
authorMatthieu Gallien <matthieu.gallien@nextcloud.com>
Mon, 1 Jul 2024 14:10:02 +0000 (16:10 +0200)
committerbackportbot[bot] <backportbot[bot]@users.noreply.github.com>
Mon, 1 Jul 2024 14:15:34 +0000 (14:15 +0000)
our current infrastructure will cause a deadlock for any hydration
requests coming from desktop files client itself

the main thread is responsible for executing the hydration request but
if the same thread is already blocked waiting for the hydration to
happen, both (open system call and hydration request handling) process
will never be completed and wait for each over in a stuck cycle

Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
src/libsync/vfs/cfapi/cfapiwrapper.cpp

index 3e2928f7bc17c1f6a1d1f680ea0d57ad6c4274e1..a5f370acbf42af8d09f5f5be8fdc97ad8fe120b3 100644 (file)
@@ -157,6 +157,12 @@ void CALLBACK cfApiFetchDataCallback(const CF_CALLBACK_INFO *callbackInfo, const
                               callbackInfo->FileSize.QuadPart);
     };
 
+    if (QCoreApplication::applicationPid() == callbackInfo->ProcessInfo->ProcessId) {
+        qCCritical(lcCfApiWrapper) << "implicit hydration triggered by the client itself. Will lead to a deadlock. Cancel";
+        sendTransferError();
+        return;
+    }
+
     auto vfs = reinterpret_cast<OCC::VfsCfApi *>(callbackInfo->CallbackContext);
     Q_ASSERT(vfs->metaObject()->className() == QByteArrayLiteral("OCC::VfsCfApi"));
     const auto path = QString(QString::fromWCharArray(callbackInfo->VolumeDosName) + QString::fromWCharArray(callbackInfo->NormalizedPath));