• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.11.5 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • io
kdirwatch_p.h
Go to the documentation of this file.
1 /* Private Header for class of KDirWatchPrivate
2  *
3  * this separate header file is needed for MOC processing
4  * because KDirWatchPrivate has signals and slots
5  *
6  * This file is part of the KDE libraries
7  * Copyright (C) 1998 Sven Radej <sven@lisa.exp.univie.ac.at>
8  * Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
9  * Copyright (C) 2007 Flavio Castelli <flavio.castelli@gmail.com>
10  * Copyright (C) 2008 JarosÅ‚aw Staniek <staniek@kde.org>
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Library General Public
14  * License version 2 as published by the Free Software Foundation.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public License
22  * along with this library; see the file COPYING.LIB. If not, write to
23  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24  * Boston, MA 02110-1301, USA.
25  */
26 
27 #ifndef KDIRWATCH_P_H
28 #define KDIRWATCH_P_H
29 
30 #include <io/config-kdirwatch.h>
31 #include "kdirwatch.h"
32 
33 #ifndef QT_NO_FILESYSTEMWATCHER
34 #define HAVE_QFILESYSTEMWATCHER
35 #endif
36 
37 #include <QtCore/QList>
38 #include <QtCore/QSet>
39 #include <QtCore/QMap>
40 #include <QtCore/QObject>
41 #include <QtCore/QString>
42 #include <QtCore/QTimer>
43 class QFileSystemWatcher;
44 class QSocketNotifier;
45 
46 #ifdef HAVE_FAM
47 #include <limits.h>
48 #include <fam.h>
49 #endif
50 
51 #ifdef HAVE_SYS_INOTIFY_H
52 #include <unistd.h>
53 #include <fcntl.h>
54 #include <sys/inotify.h>
55 
56 #ifndef IN_DONT_FOLLOW
57 #define IN_DONT_FOLLOW 0x02000000
58 #endif
59 
60 #ifndef IN_ONLYDIR
61 #define IN_ONLYDIR 0x01000000
62 #endif
63 
64 #endif
65 
66 #include <sys/time.h>
67 #include <sys/param.h> // ino_t
68 #include <ctime>
69 
70 
71 #define invalid_ctime ((time_t)-1)
72 
73 #ifdef HAVE_QFILESYSTEMWATCHER
74 #include <QtCore/QFileSystemWatcher>
75 
76 #if defined Q_WS_WIN
77 /* Helper implemented as a workaround for limitation on Windows:
78  * the maximum number of object handles is MAXIMUM_WAIT_OBJECTS (64) per thread.
79  *
80  * From http://msdn.microsoft.com/en-us/library/ms687025(VS.85).aspx
81  * "To wait on more than MAXIMUM_WAIT_OBJECTS handles, create a thread to wait
82  * on MAXIMUM_WAIT_OBJECTS handles, then wait on that thread plus the other handles.
83  * Use this technique to break the handles into groups of MAXIMUM_WAIT_OBJECTS."
84  *
85  * QFileSystemWatcher is implemented as thread, so KFileSystemWatcher
86  * allocates more QFileSystemWatcher instances on demand (and deallocates them later).
87  */
88 class KFileSystemWatcher : public QObject
89 {
90  Q_OBJECT
91 public:
92  KFileSystemWatcher();
93  ~KFileSystemWatcher();
94  void addPath(const QString &file);
95  void removePath(const QString &file);
96 
97 Q_SIGNALS:
98  void fileChanged(const QString &path);
99  void directoryChanged(const QString &path);
100 
101 private:
102  QFileSystemWatcher* availableWatcher();
103  QFileSystemWatcher* m_recentWatcher;
104  QList<QFileSystemWatcher*> m_watchers;
105  QHash<QFileSystemWatcher*, uint> m_usedObjects;
106  QHash<QString,QFileSystemWatcher*> m_paths;
107 };
108 #else
109 typedef QFileSystemWatcher KFileSystemWatcher;
110 #endif
111 #endif
112 
113 /* KDirWatchPrivate is a singleton and does the watching
114  * for every KDirWatch instance in the application.
115  */
116 class KDirWatchPrivate : public QObject
117 {
118  Q_OBJECT
119 public:
120 
121  enum entryStatus { Normal = 0, NonExistent };
122  enum entryMode { UnknownMode = 0, StatMode, DNotifyMode, INotifyMode, FAMMode, QFSWatchMode };
123  enum { NoChange=0, Changed=1, Created=2, Deleted=4 };
124 
125 
126  struct Client {
127  KDirWatch* instance;
128  int count;
129  // did the instance stop watching
130  bool watchingStopped;
131  // events blocked when stopped
132  int pending;
133  KDirWatch::WatchModes m_watchModes;
134  };
135 
136  class Entry
137  {
138  public:
139  // the last observed modification time
140  time_t m_ctime;
141  // the last observed link count
142  int m_nlink;
143  // last observed inode
144  ino_t m_ino;
145  entryStatus m_status;
146  entryMode m_mode;
147  bool isDir;
148  // instances interested in events
149  QList<Client *> m_clients;
150  // nonexistent entries of this directory
151  QList<Entry *> m_entries;
152  QString path;
153 
154  int msecLeft, freq;
155 
156  QString parentDirectory() const;
157  void addClient(KDirWatch*, KDirWatch::WatchModes);
158  void removeClient(KDirWatch*);
159  int clientCount() const;
160  bool isValid() { return m_clients.count() || m_entries.count(); }
161 
162  Entry* findSubEntry(const QString& path) const {
163  Q_FOREACH(Entry* sub_entry, m_entries) {
164  if (sub_entry->path == path)
165  return sub_entry;
166  }
167  return 0;
168  }
169 
170  bool dirty;
171  void propagate_dirty();
172 
173  QList<Client *> clientsForFileOrDir(const QString& tpath, bool* isDir) const;
174 
175 #ifdef HAVE_FAM
176  FAMRequest fr;
177 #endif
178 
179 #ifdef HAVE_SYS_INOTIFY_H
180  int wd;
181  // Creation and Deletion of files happens infrequently, so
182  // can safely be reported as they occur. File changes i.e. those that emity "dirty()" can
183  // happen many times per second, though, so maintain a list of files in this directory
184  // that can be emitted and flushed at the next slotRescan(...).
185  // This will be unused if the Entry is not a directory.
186  QList<QString> m_pendingFileChanges;
187 #endif
188  };
189 
190  typedef QMap<QString,Entry> EntryMap;
191 
192  KDirWatchPrivate();
193  ~KDirWatchPrivate();
194 
195  void resetList (KDirWatch*,bool);
196  void useFreq(Entry* e, int newFreq);
197  void addEntry(KDirWatch* instance,const QString& _path, Entry* sub_entry,
198  bool isDir, KDirWatch::WatchModes watchModes = KDirWatch::WatchDirOnly);
199  void removeEntry(KDirWatch*,const QString&, Entry* sub_entry);
200  void removeEntry(KDirWatch*,Entry* e, Entry* sub_entry);
201  bool stopEntryScan(KDirWatch*, Entry*);
202  bool restartEntryScan(KDirWatch*, Entry*, bool );
203  void stopScan(KDirWatch*);
204  void startScan(KDirWatch*, bool, bool);
205 
206  void removeEntries(KDirWatch*);
207  void statistics();
208 
209  void addWatch(Entry* entry);
210  void removeWatch(Entry* entry);
211  Entry* entry(const QString&);
212  int scanEntry(Entry* e);
213  void emitEvent(const Entry* e, int event, const QString &fileName = QString());
214 
215  // Memory management - delete when last KDirWatch gets deleted
216  void ref() { m_ref++; }
217  bool deref() { return ( --m_ref == 0 ); }
218 
219  static bool isNoisyFile( const char *filename );
220 
221 public Q_SLOTS:
222  void slotRescan();
223  void famEventReceived(); // for FAM
224  void inotifyEventReceived(); // for inotify
225  void slotRemoveDelayed();
226  void fswEventReceived(const QString &path); // for QFileSystemWatcher
227 
228 public:
229  QTimer timer;
230  EntryMap m_mapEntries;
231 
232  KDirWatch::Method m_preferredMethod, m_nfsPreferredMethod;
233  int freq;
234  int statEntries;
235  int m_nfsPollInterval, m_PollInterval;
236  int m_ref;
237  bool useStat(Entry*);
238 
239  // removeList is allowed to contain any entry at most once
240  QSet<Entry *> removeList;
241  bool delayRemove;
242 
243  bool rescan_all;
244  QTimer rescan_timer;
245 
246 #ifdef HAVE_FAM
247  QSocketNotifier *sn;
248  FAMConnection fc;
249  bool use_fam;
250 
251  void checkFAMEvent(FAMEvent*);
252  bool useFAM(Entry*);
253 #endif
254 
255 #ifdef HAVE_SYS_INOTIFY_H
256  QSocketNotifier *mSn;
257  bool supports_inotify;
258  int m_inotify_fd;
259 
260  bool useINotify(Entry*);
261 #endif
262 #ifdef HAVE_QFILESYSTEMWATCHER
263  KFileSystemWatcher *fsWatcher;
264  bool useQFSWatch(Entry* e);
265 #endif
266 
267  bool _isStopped;
268 };
269 
270 QDebug operator<<(QDebug debug, const KDirWatchPrivate::Entry &entry);
271 
272 #endif // KDIRWATCH_P_H
273 
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Mon May 5 2014 18:04:44 by doxygen 1.8.3.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.11.5 API Reference

Skip menu "kdelibs-4.11.5 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal