mirror of
https://github.com/nextcloud/desktop.git
synced 2025-10-26 11:17:43 +00:00
- fix inotify/folderwatcher so that it uses full paths
- make the test pass using QSignalSpy
This commit is contained in:
parent
e6a135273d
commit
bd5effe78c
@ -8,6 +8,7 @@
|
||||
#include <QDir>
|
||||
#include <QMutexLocker>
|
||||
#include <QStringList>
|
||||
#include <QTimer>
|
||||
|
||||
#include "mirall/inotify.h"
|
||||
#include "mirall/folderwatcher.h"
|
||||
@ -15,11 +16,6 @@
|
||||
static const uint32_t standard_event_mask =
|
||||
IN_MODIFY | IN_ATTRIB | IN_MOVE | IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT | IN_ISDIR | IN_DONT_FOLLOW;
|
||||
|
||||
// IN_ONESHOT
|
||||
// IN_ATTRIB | IN_CLOSE_WRITE | IN_CREATE |
|
||||
// IN_DELETE | IN_DELETE_SELF | IN_MOVED_FROM |
|
||||
// IN_MOVED_TO | IN_DONT_FOLLOW | IN_ONLYDIR;
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
enum SubFolderListOption {
|
||||
@ -48,26 +44,12 @@ static QStringList subFoldersList(QString folder,
|
||||
return dirList;
|
||||
}
|
||||
|
||||
FolderWatcher::FolderWatcher(const QString &path, QObject *parent)
|
||||
: QObject(parent)
|
||||
FolderWatcher::FolderWatcher(const QString &root, QObject *parent)
|
||||
: QObject(parent),
|
||||
_root(root)
|
||||
{
|
||||
_inotify = new INotify(standard_event_mask);
|
||||
_inotify->addPath(path);
|
||||
|
||||
// watch the path and all subdirectories
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
|
||||
QStringList subfolders(subFoldersList(path, SubFolderRecursive));
|
||||
if (! subfolders.empty() ) {
|
||||
qDebug() << "adding watchers for " << subfolders;
|
||||
|
||||
QStringListIterator subfoldersIt(subfolders);
|
||||
while (subfoldersIt.hasNext()) {
|
||||
_inotify->addPath(subfoldersIt.next());
|
||||
}
|
||||
}
|
||||
}
|
||||
slotAddFolderRecursive(root);
|
||||
QObject::connect(_inotify, SIGNAL(notifyEvent(int, const QString &)),
|
||||
SLOT(slotDirectoryChanged(int, const QString &)));
|
||||
}
|
||||
@ -82,44 +64,50 @@ QStringList FolderWatcher::folders() const
|
||||
return _inotify->directories();
|
||||
}
|
||||
|
||||
void FolderWatcher::slotDirectoryChanged(int mask, const QString &path)
|
||||
void FolderWatcher::slotAddFolderRecursive(const QString &path)
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
|
||||
qDebug() << mask << " : changed: " << path;
|
||||
|
||||
qDebug() << "updating subdirectories";
|
||||
|
||||
qDebug() << "Recursive adding " << path;
|
||||
QStringList watchedFolders(_inotify->directories());
|
||||
QStringListIterator watchedFoldersIt(watchedFolders);
|
||||
|
||||
while (watchedFoldersIt.hasNext()) {
|
||||
QDir folder (watchedFoldersIt.next());
|
||||
if (!folder.exists()){
|
||||
qDebug() << "Removing " << folder.path();
|
||||
_inotify->removePath(folder.path());
|
||||
}
|
||||
}
|
||||
|
||||
//qDebug() << "Removing " << folder.path();
|
||||
|
||||
qDebug() << "currently watching " << watchedFolders;
|
||||
QStringListIterator subfoldersIt(subFoldersList(path, SubFolderRecursive));
|
||||
while (subfoldersIt.hasNext()) {
|
||||
QDir folder (subfoldersIt.next());
|
||||
if (folder.exists() && !watchedFolders.contains(folder.path())) {
|
||||
qDebug() << "Adding " << folder.path();
|
||||
qDebug() << "`-> adding " << folder.path();
|
||||
_inotify->addPath(folder.path());
|
||||
}
|
||||
else
|
||||
qDebug() << "discarding " << folder.path();
|
||||
|
||||
|
||||
// Look if some of the subdirectories disappeared
|
||||
|
||||
|
||||
qDebug() << "`-> discarding " << folder.path();
|
||||
}
|
||||
qDebug() << "`-> adding " << path;
|
||||
_inotify->addPath(path);
|
||||
}
|
||||
|
||||
void FolderWatcher::slotDirectoryChanged(int mask, const QString &path)
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
|
||||
if (mask & IN_CREATE) {
|
||||
qDebug() << "CREATE: " << path;
|
||||
if (QFileInfo(path).isDir()) {
|
||||
slotAddFolderRecursive(path);
|
||||
}
|
||||
}
|
||||
else if (mask & IN_DELETE) {
|
||||
qDebug() << "DELETE: " << path;
|
||||
if (_inotify->directories().contains(path));
|
||||
qDebug() << "`-> removing " << path;
|
||||
_inotify->removePath(path);
|
||||
}
|
||||
else if (mask & IN_MODIFY) {
|
||||
qDebug() << "MODIFIED: " << path;
|
||||
}
|
||||
else if (mask & IN_MOVE) {
|
||||
qDebug() << "MOVE: " << path;
|
||||
}
|
||||
else {
|
||||
qDebug() << "OTHER " << mask << " :" << path;
|
||||
}
|
||||
emit folderChanged(path);
|
||||
}
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ class FolderWatcher : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FolderWatcher(const QString &path, QObject *parent = 0L);
|
||||
FolderWatcher(const QString &root, QObject *parent = 0L);
|
||||
~FolderWatcher();
|
||||
|
||||
QStringList folders() const;
|
||||
@ -24,9 +24,12 @@ signals:
|
||||
void folderChanged(const QString &path);
|
||||
protected slots:
|
||||
void slotDirectoryChanged(int mask, const QString &path);
|
||||
void slotAddFolderRecursive(const QString &path);
|
||||
private:
|
||||
|
||||
QMutex _mutex;
|
||||
INotify *_inotify;
|
||||
QString _root;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -38,17 +38,14 @@ INotify::~INotify()
|
||||
s_thread->unregisterForNotification(this);
|
||||
|
||||
// Remove all inotify watchs.
|
||||
QMap<QString, int>::const_iterator it;
|
||||
for (it = _wds.begin(); it != _wds.end(); ++it) {
|
||||
inotify_rm_watch(s_fd, *it);
|
||||
}
|
||||
QString key;
|
||||
foreach (key, _wds.keys())
|
||||
inotify_rm_watch(s_fd, _wds.value(key));
|
||||
}
|
||||
|
||||
void INotify::addPath(const QString &path)
|
||||
{
|
||||
// Add an inotify watch.
|
||||
qDebug() << path;
|
||||
|
||||
path.toAscii().constData();
|
||||
|
||||
int wd = inotify_add_watch(s_fd, path.toAscii().constData(), _mask);
|
||||
@ -88,9 +85,11 @@ INotify::INotifyThread::registerForNotification(INotify* notifier, int wd)
|
||||
}
|
||||
|
||||
void
|
||||
INotify::fireEvent(int mask, char* name)
|
||||
INotify::fireEvent(int mask, int wd, char* name)
|
||||
{
|
||||
emit notifyEvent(mask, QString::fromUtf8(name));
|
||||
QString path;
|
||||
foreach (path, _wds.keys(wd))
|
||||
emit notifyEvent(mask, path + "/" + QString::fromUtf8(name));
|
||||
}
|
||||
|
||||
void
|
||||
@ -138,7 +137,7 @@ INotify::INotifyThread::run()
|
||||
// with the help of watch descriptor, retrieve, corresponding INotify
|
||||
n = _map[event->wd];
|
||||
// fire event
|
||||
n->fireEvent(event->mask, event->name);
|
||||
n->fireEvent(event->mask, event->wd, event->name);
|
||||
// increment counter
|
||||
i += sizeof(struct inotify_event) + event->len;
|
||||
}
|
||||
|
||||
@ -12,7 +12,6 @@ http://www.gnu.org/licenses/gpl.txt .
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QThread>
|
||||
|
||||
@ -53,13 +52,13 @@ private:
|
||||
};
|
||||
|
||||
//INotify(int wd);
|
||||
void fireEvent(int mask, char *name);
|
||||
void fireEvent(int mask, int wd, char *name);
|
||||
static int s_fd;
|
||||
static INotifyThread* s_thread;
|
||||
|
||||
// the mask is shared for all paths
|
||||
int _mask;
|
||||
QMap<QString, int> _wds;
|
||||
QHash<QString, int> _wds;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -29,9 +29,19 @@ void TestFolderWatcher::testFilesAdded()
|
||||
|
||||
qDebug() << "Monitored: " << watcher.folders();
|
||||
|
||||
QDir subdir = QDir(tmp.path() + "/sub1/sub2");
|
||||
QVERIFY(subdir.mkpath(tmp.path() + "/sub1/sub2"));
|
||||
QDir subdir = QDir(tmp.path());
|
||||
QSignalSpy spy(&watcher, SIGNAL(folderChanged(const QString &)));
|
||||
|
||||
QVERIFY(subdir.mkpath(tmp.path() + "/sub1/sub2"));
|
||||
QVERIFY(subdir.mkpath(tmp.path() + "/sub2"));
|
||||
|
||||
while (spy.count() == 0)
|
||||
QTest::qWait(200);
|
||||
|
||||
// 2 directory changes
|
||||
QCOMPARE(spy.count(), 2);
|
||||
|
||||
qDebug() << "Monitored: " << watcher.folders();
|
||||
}
|
||||
|
||||
QTEST_MAIN(TestFolderWatcher)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user