diff options
-rw-r--r-- | src/gui/folderwatcher.cpp | 5 | ||||
-rw-r--r-- | src/gui/folderwatcher.h | 21 | ||||
-rw-r--r-- | src/gui/folderwatcher_linux.cpp | 6 | ||||
-rw-r--r-- | src/gui/folderwatcher_win.cpp | 3 | ||||
-rw-r--r-- | src/gui/folderwatcher_win.h | 1 |
5 files changed, 34 insertions, 2 deletions
diff --git a/src/gui/folderwatcher.cpp b/src/gui/folderwatcher.cpp index 0f5fee413..443956d19 100644 --- a/src/gui/folderwatcher.cpp +++ b/src/gui/folderwatcher.cpp @@ -68,6 +68,11 @@ bool FolderWatcher::pathIsIgnored(const QString &path) return false; } +bool FolderWatcher::isReliable() const +{ + return _isReliable; +} + void FolderWatcher::changeDetected(const QString &path) { QStringList paths(path); diff --git a/src/gui/folderwatcher.h b/src/gui/folderwatcher.h index 334abf1b7..ac40a2ea3 100644 --- a/src/gui/folderwatcher.h +++ b/src/gui/folderwatcher.h @@ -72,13 +72,29 @@ public: /* Check if the path is ignored. */ bool pathIsIgnored(const QString &path); + /** + * Returns false if the folder watcher can't be trusted to capture all + * notifications. + * + * For example, this can happen on linux if the inotify user limit from + * /proc/sys/fs/inotify/max_user_watches is exceeded. + */ + bool isReliable() const; + signals: /** Emitted when one of the watched directories or one * of the contained files is changed. */ void pathChanged(const QString &path); - /** Emitted if an error occurs */ - void error(const QString &error); + /** + * Emitted if some notifications were lost. + * + * Would happen, for example, if the number of pending notifications + * exceeded the allocated buffer size on Windows. Note that the folder + * watcher could still be able to capture all future notifications - + * i.e. isReliable() is orthogonal to losing changes occasionally. + */ + void lostChanges(); protected slots: // called from the implementations to indicate a change in path @@ -93,6 +109,7 @@ private: QTime _timer; QSet<QString> _lastPaths; Folder *_folder; + bool _isReliable = true; friend class FolderWatcherPrivate; }; diff --git a/src/gui/folderwatcher_linux.cpp b/src/gui/folderwatcher_linux.cpp index f0e0eb0e4..37d79211a 100644 --- a/src/gui/folderwatcher_linux.cpp +++ b/src/gui/folderwatcher_linux.cpp @@ -78,6 +78,12 @@ void FolderWatcherPrivate::inotifyRegisterPath(const QString &path) IN_CLOSE_WRITE | IN_ATTRIB | IN_MOVE | IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT | IN_ONLYDIR); if (wd > -1) { _watches.insert(wd, path); + } else { + // If we're running out of memory or inotify watches, become + // unreliable. + if (errno == ENOMEM || errno == ENOSPC) { + _parent->_isReliable = false; + } } } } diff --git a/src/gui/folderwatcher_win.cpp b/src/gui/folderwatcher_win.cpp index 19c623f56..4f963fbe2 100644 --- a/src/gui/folderwatcher_win.cpp +++ b/src/gui/folderwatcher_win.cpp @@ -101,6 +101,7 @@ void WatcherThread::watchChanges(size_t fileNotifyBufferSize, DWORD errorCode = GetLastError(); if (errorCode == ERROR_NOTIFY_ENUM_DIR) { qCDebug(lcFolderWatcher) << "The buffer for changes overflowed! Triggering a generic change and resizing"; + emit lostChanges(); emit changed(_path); *increaseBufferSize = true; } else { @@ -199,6 +200,8 @@ FolderWatcherPrivate::FolderWatcherPrivate(FolderWatcher *p, const QString &path _thread = new WatcherThread(path); connect(_thread, SIGNAL(changed(const QString &)), _parent, SLOT(changeDetected(const QString &))); + connect(_thread, SIGNAL(lostChanges()), + _parent, SIGNAL(lostChanges())); _thread->start(); } diff --git a/src/gui/folderwatcher_win.h b/src/gui/folderwatcher_win.h index 687ec891d..7ea673084 100644 --- a/src/gui/folderwatcher_win.h +++ b/src/gui/folderwatcher_win.h @@ -53,6 +53,7 @@ protected: signals: void changed(const QString &path); + void lostChanges(); private: QString _path; |