mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-26 23:28:14 +03:00
Infrastructure for inotify. To replace QFileSystemWatcher, which, due
to a Qt bug, can't see modified files. See http://qt.gitorious.org/qt/qt/merge_requests/2301
This commit is contained in:
parent
b7a3fc7ab8
commit
5294bee2bf
6 changed files with 198 additions and 0 deletions
|
@ -8,6 +8,7 @@ mirall/application.cpp
|
|||
mirall/folder.cpp
|
||||
mirall/gitfolder.cpp
|
||||
mirall/folderwatcher.cpp
|
||||
mirall/inotify.cpp
|
||||
main.cpp)
|
||||
|
||||
qt4_automoc(${mirall_SRCS})
|
||||
|
|
|
@ -8,12 +8,15 @@
|
|||
#include "mirall/application.h"
|
||||
#include "mirall/folder.h"
|
||||
#include "mirall/gitfolder.h"
|
||||
#include "mirall/inotify.h"
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
Application::Application(int argc, char **argv) :
|
||||
QApplication(argc, argv)
|
||||
{
|
||||
INotify::initialize();
|
||||
|
||||
_folder = new GitFolder(QDir::homePath() + "/Mirall", this);
|
||||
setApplicationName("Mirall");
|
||||
setupActions();
|
||||
|
@ -23,6 +26,7 @@ Application::Application(int argc, char **argv) :
|
|||
|
||||
Application::~Application()
|
||||
{
|
||||
INotify::cleanup();
|
||||
}
|
||||
|
||||
void Application::setupActions()
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
|
||||
// event masks
|
||||
#include <sys/inotify.h>
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QFlags>
|
||||
|
@ -7,8 +10,14 @@
|
|||
#include <QMutexLocker>
|
||||
#include <QStringList>
|
||||
|
||||
#include "mirall/inotify.h"
|
||||
#include "mirall/folderwatcher.h"
|
||||
|
||||
static const uint32_t standard_event_mask =
|
||||
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 {
|
||||
|
@ -41,6 +50,8 @@ FolderWatcher::FolderWatcher(const QString &path, QObject *parent)
|
|||
: QObject(parent)
|
||||
{
|
||||
_watcher = new QFileSystemWatcher(this);
|
||||
_inotify = new INotify(path, standard_event_mask);
|
||||
|
||||
|
||||
// watch the path and all subdirectories
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
|
||||
#ifndef MIRALL_FOLDERWATCHER_H
|
||||
#define MIRALL_FOLDERWATCHER_H
|
||||
|
||||
|
@ -6,7 +7,10 @@
|
|||
#include <QString>
|
||||
#include <QMutex>
|
||||
|
||||
#include "mirall/inotify.h"
|
||||
|
||||
class QFileSystemWatcher;
|
||||
class INotify;
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
|
@ -23,6 +27,7 @@ protected slots:
|
|||
private:
|
||||
QFileSystemWatcher *_watcher;
|
||||
QMutex _mutex;
|
||||
INotify *_inotify;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
118
src/mirall/inotify.cpp
Normal file
118
src/mirall/inotify.cpp
Normal file
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
Based on example by:
|
||||
Copyright (c) Ashish Shukla
|
||||
|
||||
This is licensed under GNU GPL v2 or later.
|
||||
For license text, Refer to the the file COPYING or visit
|
||||
http://www.gnu.org/licenses/gpl.txt .
|
||||
*/
|
||||
|
||||
#include <sys/inotify.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "inotify.h"
|
||||
|
||||
// Buffer Size for read() buffer
|
||||
#define BUFFERSIZE 512
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
// Allocate space for static members of class.
|
||||
int INotify::s_fd;
|
||||
INotify::INotifyThread* INotify::s_thread;
|
||||
|
||||
INotify::INotify(int wd) : _wd(wd)
|
||||
{
|
||||
}
|
||||
|
||||
INotify::INotify(const QString &path, int 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()
|
||||
{
|
||||
// Unregister from iNotifier thread.
|
||||
s_thread->unregisterForNotification(this);
|
||||
|
||||
// Remove the inotify watch.
|
||||
inotify_rm_watch(s_fd, _wd);
|
||||
}
|
||||
|
||||
void
|
||||
INotify::INotifyThread::unregisterForNotification(INotify* notifier)
|
||||
{
|
||||
_map.remove(notifier->_wd);
|
||||
}
|
||||
|
||||
void
|
||||
INotify::INotifyThread::registerForNotification(INotify* notifier)
|
||||
{
|
||||
_map[notifier->_wd] = notifier;
|
||||
}
|
||||
|
||||
void
|
||||
INotify::fireEvent(int mask, char* name)
|
||||
{
|
||||
emit notifyEvent(mask, QString::fromUtf8(name));
|
||||
}
|
||||
|
||||
void
|
||||
INotify::initialize()
|
||||
{
|
||||
s_fd = inotify_init();
|
||||
s_thread = new INotifyThread(s_fd);
|
||||
s_thread->start();
|
||||
}
|
||||
|
||||
void
|
||||
INotify::cleanup()
|
||||
{
|
||||
close(s_fd);
|
||||
s_thread->terminate();
|
||||
s_thread->wait(3000);
|
||||
delete s_thread;
|
||||
}
|
||||
|
||||
INotify::INotifyThread::INotifyThread(int fd) : _fd(fd)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Thread routine
|
||||
void
|
||||
INotify::INotifyThread::run()
|
||||
{
|
||||
int len;
|
||||
struct inotify_event* event;
|
||||
char buffer[BUFFERSIZE];
|
||||
INotify* n = NULL;
|
||||
int i;
|
||||
|
||||
// read the inotify file descriptor.
|
||||
while((len = read(_fd, buffer, BUFFERSIZE)) > 0)
|
||||
{
|
||||
// reset counter
|
||||
i = 0;
|
||||
// while there are enough events in the buffer
|
||||
while(i + sizeof(struct inotify_event) < len)
|
||||
{
|
||||
// cast an inotify_event
|
||||
event = (struct inotify_event*)&buffer[i];
|
||||
// with the help of watch descriptor, retrieve, corresponding INotify
|
||||
n = _map[event->wd];
|
||||
// fire event
|
||||
n->fireEvent(event->mask, event->name);
|
||||
// increment counter
|
||||
i += sizeof(struct inotify_event) + event->len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // ns mirall
|
||||
|
||||
#include "inotify.moc"
|
59
src/mirall/inotify.h
Normal file
59
src/mirall/inotify.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
Based on example by:
|
||||
Copyright (c) Ashish Shukla
|
||||
|
||||
This is licensed under GNU GPL v2 or later.
|
||||
For license text, Refer to the the file COPYING or visit
|
||||
http://www.gnu.org/licenses/gpl.txt .
|
||||
*/
|
||||
|
||||
#ifndef MIRALL_INOTIFY_H
|
||||
#define MIRALL_INOTIFY_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
#include <QThread>
|
||||
|
||||
namespace Mirall
|
||||
{
|
||||
|
||||
class INotify : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
INotify(const QString &name, int mask);
|
||||
~INotify();
|
||||
|
||||
static void initialize();
|
||||
static void cleanup();
|
||||
|
||||
signals:
|
||||
|
||||
void notifyEvent(int mask, const QString &name);
|
||||
|
||||
private:
|
||||
class INotifyThread : public QThread
|
||||
{
|
||||
int _fd;
|
||||
QHash<int, INotify*> _map;
|
||||
public:
|
||||
INotifyThread(int fd);
|
||||
void registerForNotification(INotify*);
|
||||
void unregisterForNotification(INotify*);
|
||||
protected:
|
||||
void run();
|
||||
};
|
||||
|
||||
INotify(int wd);
|
||||
void fireEvent(int mask, char *name);
|
||||
static int s_fd;
|
||||
static INotifyThread* s_thread;
|
||||
int _wd;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue