kdelibs/kdecore/io/kdirwatch_p.h
Ivailo Monev 3d12c6d2e8 generic: use QFilesystemWatcher instead of inotify directly
this allows for less complexity and more abstraction offloaded to
Qt itself which supports dnotify, inotify, kqueue and fsevents.

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
2016-04-29 15:28:27 +00:00

201 lines
5.2 KiB
C++

/* Private Header for class of KDirWatchPrivate
*
* this separate header file is needed for MOC processing
* because KDirWatchPrivate has signals and slots
*
* This file is part of the KDE libraries
* Copyright (C) 1998 Sven Radej <sven@lisa.exp.univie.ac.at>
* Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
* Copyright (C) 2007 Flavio Castelli <flavio.castelli@gmail.com>
* Copyright (C) 2008 Jarosław Staniek <staniek@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KDIRWATCH_P_H
#define KDIRWATCH_P_H
#include <io/config-kdirwatch.h>
#include "kdirwatch.h"
#include <QtCore/qset.h>
#include <QtCore/qmap.h>
#include <QtCore/qobject.h>
#include <QtCore/qtimer.h>
class QFileSystemWatcher;
class QSocketNotifier;
#ifdef HAVE_FAM
#include <limits.h>
#include <fam.h>
#endif
#include <sys/time.h>
#include <sys/param.h> // ino_t
#include <sys/stat.h> // ino_t
#include <ctime>
#define invalid_ctime ((time_t)-1)
#ifndef QT_NO_FILESYSTEMWATCHER
#include <QtCore/qfilesystemwatcher.h>
typedef QFileSystemWatcher KFileSystemWatcher;
#endif
/* KDirWatchPrivate is a singleton and does the watching
* for every KDirWatch instance in the application.
*/
class KDirWatchPrivate : public QObject
{
Q_OBJECT
public:
enum entryStatus { Normal = 0, NonExistent };
enum entryMode { UnknownMode = 0, FAMMode, QFSWatchMode };
enum { NoChange=0, Changed=1, Created=2, Deleted=4 };
struct Client {
KDirWatch* instance;
int count;
// did the instance stop watching
bool watchingStopped;
// events blocked when stopped
int pending;
KDirWatch::WatchModes m_watchModes;
};
class Entry
{
public:
// the last observed modification time
time_t m_ctime;
// the last observed link count
int m_nlink;
// last observed inode
ino_t m_ino;
entryStatus m_status;
entryMode m_mode;
bool isDir;
// instances interested in events
QList<Client *> m_clients;
// nonexistent entries of this directory
QList<Entry *> m_entries;
QString path;
int msecLeft, freq;
QString parentDirectory() const;
void addClient(KDirWatch*, KDirWatch::WatchModes);
void removeClient(KDirWatch*);
int clientCount() const;
bool isValid() { return m_clients.count() || m_entries.count(); }
Entry* findSubEntry(const QString& path) const {
Q_FOREACH(Entry* sub_entry, m_entries) {
if (sub_entry->path == path)
return sub_entry;
}
return 0;
}
bool dirty;
void propagate_dirty();
QList<Client *> clientsForFileOrDir(const QString& tpath, bool* isDir) const;
#ifdef HAVE_FAM
FAMRequest fr;
#endif
};
typedef QMap<QString,Entry> EntryMap;
KDirWatchPrivate();
~KDirWatchPrivate();
void resetList (KDirWatch*,bool);
void useFreq(Entry* e, int newFreq);
void addEntry(KDirWatch* instance,const QString& _path, Entry* sub_entry,
bool isDir, KDirWatch::WatchModes watchModes = KDirWatch::WatchDirOnly);
bool removeEntry(KDirWatch*,const QString&, Entry* sub_entry);
void removeEntry(KDirWatch*,Entry* e, Entry* sub_entry);
bool stopEntryScan(KDirWatch*, Entry*);
bool restartEntryScan(KDirWatch*, Entry*, bool );
void stopScan(KDirWatch*);
void startScan(KDirWatch*, bool, bool);
void removeEntries(KDirWatch*);
void statistics();
void addWatch(Entry* entry);
void removeWatch(Entry* entry);
Entry* entry(const QString&);
int scanEntry(Entry* e);
void emitEvent(const Entry* e, int event, const QString &fileName = QString());
// Memory management - delete when last KDirWatch gets deleted
void ref() { m_ref++; }
bool deref() { return ( --m_ref == 0 ); }
static bool isNoisyFile( const char *filename );
public Q_SLOTS:
void slotRescan();
void famEventReceived(); // for FAM
void slotRemoveDelayed();
void fswEventReceived(const QString &path); // for QFileSystemWatcher
public:
QTimer timer;
EntryMap m_mapEntries;
KDirWatch::Method m_preferredMethod, m_nfsPreferredMethod;
int freq;
int statEntries;
int m_nfsPollInterval, m_PollInterval;
int m_ref;
// removeList is allowed to contain any entry at most once
QSet<Entry *> removeList;
bool delayRemove;
bool rescan_all;
QTimer rescan_timer;
#ifdef HAVE_FAM
QSocketNotifier *sn;
FAMConnection fc;
bool use_fam;
void checkFAMEvent(FAMEvent*);
bool useFAM(Entry*);
#endif
#ifndef QT_NO_FILESYSTEMWATCHER
KFileSystemWatcher *fsWatcher;
bool useQFSWatch(Entry* e);
#endif
bool _isStopped;
};
QDebug operator<<(QDebug debug, const KDirWatchPrivate::Entry &entry);
#endif // KDIRWATCH_P_H