Make the inotify interface work with multiple paths

This commit is contained in:
Duncan Mac-Vicar P 2011-03-17 07:13:30 +01:00
parent 5294bee2bf
commit 03194d3aae
4 changed files with 72 additions and 27 deletions

View File

@ -50,8 +50,8 @@ FolderWatcher::FolderWatcher(const QString &path, QObject *parent)
: QObject(parent)
{
_watcher = new QFileSystemWatcher(this);
_inotify = new INotify(path, standard_event_mask);
_inotify = new INotify(standard_event_mask);
//_inotify->addPath(path);
// watch the path and all subdirectories
{
@ -63,11 +63,14 @@ FolderWatcher::FolderWatcher(const QString &path, QObject *parent)
QStringListIterator subfoldersIt(subfolders);
while (subfoldersIt.hasNext()) {
_watcher->addPath(subfoldersIt.next());
_inotify->addPath(subfoldersIt.next());
}
}
QObject::connect(_watcher, SIGNAL(directoryChanged(const QString &)),
SLOT(slotDirectoryChanged(const QString &)));
// QObject::connect(_watcher, SIGNAL(directoryChanged(const QString &)),
// SLOT(slotDirectoryChanged(const QString &)));
QObject::connect(_inotify, SIGNAL(notifyEvent(int, const QString &)),
SLOT(slotDirectoryChanged(int, const QString &)));
}
FolderWatcher::~FolderWatcher()
@ -75,22 +78,22 @@ FolderWatcher::~FolderWatcher()
}
void FolderWatcher::slotDirectoryChanged(const QString &path)
void FolderWatcher::slotDirectoryChanged(int mask, const QString &path)
{
QMutexLocker locker(&_mutex);
qDebug() << "changed: " << path;
qDebug() << mask << " : changed: " << path;
qDebug() << "updating subdirectories";
QStringList watchedFolders(_watcher->directories());
QStringList watchedFolders(_inotify->directories());
QStringListIterator watchedFoldersIt(watchedFolders);
while (watchedFoldersIt.hasNext()) {
QDir folder (watchedFoldersIt.next());
if (!folder.exists()){
qDebug() << "Removing " << folder.path();
_watcher->removePath(folder.path());
_inotify->removePath(folder.path());
}
}
@ -99,7 +102,7 @@ void FolderWatcher::slotDirectoryChanged(const QString &path)
QDir folder (subfoldersIt.next());
if (folder.exists() && !watchedFolders.contains(folder.path())) {
qDebug() << "Adding " << folder.path();
_watcher->addPath(folder.path());
_inotify->addPath(folder.path());
}
// Look if some of the subdirectories disappeared

View File

@ -23,7 +23,8 @@ public:
signals:
void folderChanged(const QString &path);
protected slots:
void slotDirectoryChanged(const QString &path);
//void slotDirectoryChanged(const QString &path);
void slotDirectoryChanged(int mask, const QString &path);
private:
QFileSystemWatcher *_watcher;
QMutex _mutex;

View File

@ -9,9 +9,12 @@ http://www.gnu.org/licenses/gpl.txt .
#include <sys/inotify.h>
#include <unistd.h>
#include <QDebug>
#include <QStringList>
#include "inotify.h"
// Buffer Size for read() buffer
#define BUFFERSIZE 512
@ -21,17 +24,12 @@ namespace Mirall {
int INotify::s_fd;
INotify::INotifyThread* INotify::s_thread;
INotify::INotify(int wd) : _wd(wd)
{
}
//INotify::INotify(int wd) : _wd(wd)
//{
//}
INotify::INotify(const QString &path, int mask)
INotify::INotify(int mask) : _mask(mask)
{
// Add an inotify watch.
_wd = inotify_add_watch(s_fd, path.toUtf8().data(), mask);
// Register for iNotifycation from iNotifier thread.
s_thread->registerForNotification(this);
}
INotify::~INotify()
@ -39,20 +37,55 @@ INotify::~INotify()
// Unregister from iNotifier thread.
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);
}
}
void INotify::addPath(const QString &path)
{
// Add an inotify watch.
qDebug() << path;
path.toAscii().constData();
return;
int wd = inotify_add_watch(s_fd, path.toAscii().constData(), _mask);
_wds[path] = wd;
// Register for iNotifycation from iNotifier thread.
s_thread->registerForNotification(this, wd);
}
void INotify::removePath(const QString &path)
{
// Remove the inotify watch.
inotify_rm_watch(s_fd, _wd);
inotify_rm_watch(s_fd, _wds[path]);
}
QStringList INotify::directories() const
{
return _wds.keys();
}
void
INotify::INotifyThread::unregisterForNotification(INotify* notifier)
{
_map.remove(notifier->_wd);
//_map.remove(notifier->_wd);
QHash<int, INotify*>::iterator it;
for (it = _map.begin(); it != _map.end(); ++it) {
if (it.value() == notifier)
_map.remove(it.key());
}
}
void
INotify::INotifyThread::registerForNotification(INotify* notifier)
INotify::INotifyThread::registerForNotification(INotify* notifier, int wd)
{
_map[notifier->_wd] = notifier;
_map[wd] = notifier;
}
void

View File

@ -12,6 +12,7 @@ http://www.gnu.org/licenses/gpl.txt .
#include <QObject>
#include <QHash>
#include <QMap>
#include <QString>
#include <QThread>
@ -24,12 +25,16 @@ class INotify : public QObject
public:
INotify(const QString &name, int mask);
INotify(int mask);
~INotify();
static void initialize();
static void cleanup();
void addPath(const QString &name);
void removePath(const QString &name);
QStringList directories() const;
signals:
void notifyEvent(int mask, const QString &name);
@ -41,17 +46,20 @@ private:
QHash<int, INotify*> _map;
public:
INotifyThread(int fd);
void registerForNotification(INotify*);
void registerForNotification(INotify*, int);
void unregisterForNotification(INotify*);
protected:
void run();
};
INotify(int wd);
//INotify(int wd);
void fireEvent(int mask, char *name);
static int s_fd;
static INotifyThread* s_thread;
int _wd;
// the mask is shared for all paths
int _mask;
QMap<QString, int> _wds;
};
}