FolderWatcher: Become unreliable if test notification fails #7241

Necessary for some filesystems on windows that don't have full file
watching capabilities.
This commit is contained in:
Christian Kamm 2019-06-13 09:59:01 +02:00
parent 2bba296e96
commit 831e718b0c
4 changed files with 39 additions and 1 deletions

View File

@ -1194,6 +1194,7 @@ void Folder::registerFolderWatcher()
connect(_folderWatcher.data(), &FolderWatcher::becameUnreliable,
this, &Folder::slotWatcherUnreliable);
_folderWatcher->init(path());
_folderWatcher->startNotificatonTest(path() + QLatin1String(".owncloudsync.log"));
}
bool Folder::supportsVirtualFiles() const

View File

@ -33,6 +33,7 @@
#endif
#include "folder.h"
#include "filesystem.h"
namespace OCC {
@ -75,6 +76,26 @@ bool FolderWatcher::isReliable() const
return _isReliable;
}
void FolderWatcher::startNotificatonTest(const QString &path)
{
ASSERT(_testNotificationPath.isEmpty());
_testNotificationPath = path;
if (QFile::exists(path)) {
auto mtime = FileSystem::getModTime(path);
FileSystem::setModTime(path, mtime + 1);
} else {
QFile f(path);
f.open(QIODevice::WriteOnly | QIODevice::Append);
}
QTimer::singleShot(5000, this, [&]() {
if (!_testNotificationPath.isEmpty())
emit becameUnreliable(tr("The watcher did not receive a test notification."));
_testNotificationPath.clear();
});
}
int FolderWatcher::testLinuxWatchCount() const
{
#ifdef Q_OS_LINUX
@ -111,6 +132,10 @@ void FolderWatcher::changeDetected(const QStringList &paths)
// ------- handle ignores:
for (int i = 0; i < paths.size(); ++i) {
QString path = paths[i];
if (!_testNotificationPath.isEmpty()
&& Utility::fileNamesEqual(path, _testNotificationPath)) {
_testNotificationPath.clear();
}
if (pathIsIgnored(path)) {
continue;
}

View File

@ -71,6 +71,14 @@ public:
*/
bool isReliable() const;
/**
* Triggers a change in the path and verifies a notification arrives.
*
* If no notification is seen, the folderwatcher marks itself as unreliable.
* The path must be ignored by the watcher.
*/
void startNotificatonTest(const QString &path);
/// For testing linux behavior only
int testLinuxWatchCount() const;
@ -110,6 +118,9 @@ private:
Folder *_folder;
bool _isReliable = true;
/** Path of the expected test notification */
QString _testNotificationPath;
friend class FolderWatcherPrivate;
};
}

View File

@ -171,9 +171,10 @@ void FolderWatcherPrivate::slotReceivedNotification(int fd)
if (event->len == 0 || event->wd <= -1)
continue;
QByteArray fileName(event->name);
// Filter out journal changes - redundant with filtering in
// FolderWatcher::pathIsIgnored.
if (fileName.startsWith("._sync_")
|| fileName.startsWith(".csync_journal.db")
|| fileName.startsWith(".owncloudsync.log")
|| fileName.startsWith(".sync_")) {
continue;
}