summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Burchell <robin.burchell@collabora.com>2012-01-03 21:31:08 +0100
committerQt by Nokia <qt-info@nokia.com>2012-01-05 14:35:59 +0100
commit848f53a268449e6c581737fe2930bc75967e97ce (patch)
tree5840b9a6598d7876101436f07fd4e89352a8b16e
parent8ad583b7f9cd4ab450e636bc2c0626975397aa86 (diff)
Remove OS X FSEvents watcher.
Per QTBUG-9249, this backend is buggy, and not recommended for use by Apple. Change-Id: I72ce88006a4badbbfdd825717020078778d16a36 Reviewed-by: Sergio Ahumada <sergio.ahumada@nokia.com>
-rw-r--r--src/corelib/io/io.pri3
-rw-r--r--src/corelib/io/qfilesystemwatcher.cpp10
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.cpp492
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents_p.h132
4 files changed, 2 insertions, 635 deletions
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index 380714ea54..d7eb7109a1 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -92,9 +92,8 @@ win32 {
io/qfilesystemiterator_unix.cpp \
!nacl:macx-*: {
- HEADERS += io/qfilesystemwatcher_fsevents_p.h
SOURCES += io/qfilesystemengine_mac.cpp
- SOURCES += io/qsettings_mac.cpp io/qfilesystemwatcher_fsevents.cpp
+ SOURCES += io/qsettings_mac.cpp
}
macx-*: {
SOURCES += io/qstandardpaths_mac.cpp
diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp
index 4e9ac9b689..580239d209 100644
--- a/src/corelib/io/qfilesystemwatcher.cpp
+++ b/src/corelib/io/qfilesystemwatcher.cpp
@@ -59,9 +59,6 @@
#elif defined(Q_OS_LINUX)
# include "qfilesystemwatcher_inotify_p.h"
#elif defined(Q_OS_FREEBSD) || defined(Q_OS_MAC)
-# if (defined Q_OS_MAC) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
-# include "qfilesystemwatcher_fsevents_p.h"
-# endif //MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
# include "qfilesystemwatcher_kqueue_p.h"
#endif
@@ -76,12 +73,7 @@ QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine()
// 2005), so we can't just new inotify directly.
return QInotifyFileSystemWatcherEngine::create();
#elif defined(Q_OS_FREEBSD) || defined(Q_OS_MAC)
-# if 0 && defined(Q_OS_MAC) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5)
- return QFSEventsFileSystemWatcherEngine::create();
- else
-# endif
- return QKqueueFileSystemWatcherEngine::create();
+ return QKqueueFileSystemWatcherEngine::create();
#else
return 0;
#endif
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.cpp b/src/corelib/io/qfilesystemwatcher_fsevents.cpp
deleted file mode 100644
index 8f7094f9e7..0000000000
--- a/src/corelib/io/qfilesystemwatcher_fsevents.cpp
+++ /dev/null
@@ -1,492 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#define _DARWIN_USE_64_BIT_INODE
-#include <qplatformdefs.h>
-
-#include "qfilesystemwatcher.h"
-#include "qfilesystemwatcher_fsevents_p.h"
-
-#ifndef QT_NO_FILESYSTEMWATCHER
-
-#include <qdebug.h>
-#include <qfile.h>
-#include <qdatetime.h>
-#include <qfileinfo.h>
-#include <qvarlengtharray.h>
-
-#include <mach/mach.h>
-#include <sys/types.h>
-#include <CoreFoundation/CFRunLoop.h>
-#include <CoreFoundation/CFUUID.h>
-#include <CoreServices/CoreServices.h>
-#include <AvailabilityMacros.h>
-#include <private/qcore_mac_p.h>
-
-QT_BEGIN_NAMESPACE
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-// Static operator overloading so for the sake of some convieniece.
-// They only live in this compilation unit to avoid polluting Qt in general.
-static bool operator==(const struct ::timespec &left, const struct ::timespec &right)
-{
- return left.tv_sec == right.tv_sec
- && left.tv_nsec == right.tv_nsec;
-}
-
-static bool operator==(const struct ::stat &left, const struct ::stat &right)
-{
- return left.st_dev == right.st_dev
- && left.st_mode == right.st_mode
- && left.st_size == right.st_size
- && left.st_ino == right.st_ino
- && left.st_uid == right.st_uid
- && left.st_gid == right.st_gid
- && left.st_mtimespec == right.st_mtimespec
- && left.st_ctimespec == right.st_ctimespec
- && left.st_flags == right.st_flags;
-}
-
-static bool operator!=(const struct ::stat &left, const struct ::stat &right)
-{
- return !(operator==(left, right));
-}
-
-
-static void addPathToHash(PathHash &pathHash, const QString &key, const QFileInfo &fileInfo,
- const QString &path)
-{
- PathInfoList &list = pathHash[key];
- list.push_back(PathInfo(path,
- fileInfo.canonicalFilePath().normalized(QString::NormalizationForm_D).toUtf8()));
- pathHash.insert(key, list);
-}
-
-static void removePathFromHash(PathHash &pathHash, const QString &key, const QString &path)
-{
- PathInfoList &list = pathHash[key];
- // We make the assumption that the list contains unique paths
- PathInfoList::iterator End = list.end();
- PathInfoList::iterator it = list.begin();
- while (it != End) {
- if (it->originalPath == path) {
- list.erase(it);
- break;
- }
- ++it;
- }
- if (list.isEmpty())
- pathHash.remove(key);
-}
-
-static void stopFSStream(FSEventStreamRef stream)
-{
- if (stream) {
- FSEventStreamStop(stream);
- FSEventStreamInvalidate(stream);
- }
-}
-
-static QString createFSStreamPath(const QString &absolutePath)
-{
- // The path returned has a trailing slash, so ensure that here.
- QString string = absolutePath;
- string.reserve(string.size() + 1);
- string.append(QLatin1Char('/'));
- return string;
-}
-
-static void cleanupFSStream(FSEventStreamRef stream)
-{
- if (stream)
- FSEventStreamRelease(stream);
-}
-
-const FSEventStreamCreateFlags QtFSEventFlags = (kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagNoDefer /* | kFSEventStreamCreateFlagWatchRoot*/);
-
-const CFTimeInterval Latency = 0.033; // This will do updates 30 times a second which is probably more than you need.
-#endif
-
-QFSEventsFileSystemWatcherEngine::QFSEventsFileSystemWatcherEngine()
- : fsStream(0), pathsToWatch(0), threadsRunLoop(0)
-{
-}
-
-QFSEventsFileSystemWatcherEngine::~QFSEventsFileSystemWatcherEngine()
-{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- // I assume that at this point, QFileSystemWatcher has already called stop
- // on me, so I don't need to invalidate or stop my stream, simply
- // release it.
- cleanupFSStream(fsStream);
- if (pathsToWatch)
- CFRelease(pathsToWatch);
-#endif
-}
-
-QFSEventsFileSystemWatcherEngine *QFSEventsFileSystemWatcherEngine::create()
-{
- return new QFSEventsFileSystemWatcherEngine();
-}
-
-QStringList QFSEventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
- QStringList *files,
- QStringList *directories)
-{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- stop();
- wait();
- QMutexLocker locker(&mutex);
- QStringList failedToAdd;
- // if we have a running FSStreamEvent, we have to kill it, we'll re-add the stream soon.
- FSEventStreamEventId idToCheck;
- if (fsStream) {
- idToCheck = FSEventStreamGetLatestEventId(fsStream);
- cleanupFSStream(fsStream);
- } else {
- idToCheck = kFSEventStreamEventIdSinceNow;
- }
-
- // Brain-dead approach, but works. FSEvents actually can already read sub-trees, but since it's
- // work to figure out if we are doing a double register, we just register it twice as FSEvents
- // seems smart enough to only deliver one event. We also duplicate directory entries in here
- // (e.g., if you watch five files in the same directory, you get that directory included in the
- // array 5 times). This stupidity also makes remove work correctly though. I'll freely admit
- // that we could make this a bit smarter. If you do, check the auto-tests, they should catch at
- // least a couple of the issues.
- QCFType<CFMutableArrayRef> tmpArray = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
- for (int i = 0; i < paths.size(); ++i) {
- const QString &path = paths.at(i);
-
- QFileInfo fileInfo(path);
- if (!fileInfo.exists()) {
- failedToAdd.append(path);
- continue;
- }
-
- if (fileInfo.isDir()) {
- if (directories->contains(path)) {
- failedToAdd.append(path);
- continue;
- } else {
- directories->append(path);
- // Full file path for dirs.
- QCFString cfpath(createFSStreamPath(fileInfo.canonicalFilePath()));
- addPathToHash(dirPathInfoHash, cfpath, fileInfo, path);
- CFArrayAppendValue(tmpArray, cfpath);
- }
- } else {
- if (files->contains(path)) {
- failedToAdd.append(path);
- continue;
- } else {
- // Just the absolute path (minus it's filename) for files.
- QCFString cfpath(createFSStreamPath(fileInfo.canonicalPath()));
- files->append(path);
- addPathToHash(filePathInfoHash, cfpath, fileInfo, path);
- CFArrayAppendValue(tmpArray, cfpath);
- }
- }
- }
-
- if (!pathsToWatch && failedToAdd.size() == paths.size()) {
- return failedToAdd;
- }
-
- if (CFArrayGetCount(tmpArray) > 0) {
- if (pathsToWatch) {
- CFArrayAppendArray(tmpArray, pathsToWatch, CFRangeMake(0, CFArrayGetCount(pathsToWatch)));
- CFRelease(pathsToWatch);
- }
- pathsToWatch = CFArrayCreateCopy(kCFAllocatorDefault, tmpArray);
- }
-
- FSEventStreamContext context = { 0, this, 0, 0, 0 };
- fsStream = FSEventStreamCreate(kCFAllocatorDefault,
- QFSEventsFileSystemWatcherEngine::fseventsCallback,
- &context, pathsToWatch,
- idToCheck, Latency, QtFSEventFlags);
- warmUpFSEvents();
-
- return failedToAdd;
-#else
- Q_UNUSED(paths);
- Q_UNUSED(files);
- Q_UNUSED(directories);
- return QStringList();
-#endif
-}
-
-void QFSEventsFileSystemWatcherEngine::warmUpFSEvents()
-{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- // This function assumes that the mutex has already been grabbed before calling it.
- // It exits with the mutex still locked (Q_ASSERT(mutex.isLocked()) ;-).
- start();
- waitCondition.wait(&mutex);
-#endif
-}
-
-QStringList QFSEventsFileSystemWatcherEngine::removePaths(const QStringList &paths,
- QStringList *files,
- QStringList *directories)
-{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- stop();
- wait();
- QMutexLocker locker(&mutex);
- // short circuit for smarties that call remove before add and we have nothing.
- if (pathsToWatch == 0)
- return paths;
- QStringList failedToRemove;
- // if we have a running FSStreamEvent, we have to stop it, we'll re-add the stream soon.
- FSEventStreamEventId idToCheck;
- if (fsStream) {
- idToCheck = FSEventStreamGetLatestEventId(fsStream);
- cleanupFSStream(fsStream);
- fsStream = 0;
- } else {
- idToCheck = kFSEventStreamEventIdSinceNow;
- }
-
- CFIndex itemCount = CFArrayGetCount(pathsToWatch);
- QCFType<CFMutableArrayRef> tmpArray = CFArrayCreateMutableCopy(kCFAllocatorDefault, itemCount,
- pathsToWatch);
- CFRelease(pathsToWatch);
- pathsToWatch = 0;
- for (int i = 0; i < paths.size(); ++i) {
- // Get the itemCount at the beginning to avoid any overruns during the iteration.
- itemCount = CFArrayGetCount(tmpArray);
- const QString &path = paths.at(i);
- QFileInfo fi(path);
- QCFString cfpath(createFSStreamPath(fi.canonicalPath()));
-
- CFIndex index = CFArrayGetFirstIndexOfValue(tmpArray, CFRangeMake(0, itemCount), cfpath);
- if (index != -1) {
- CFArrayRemoveValueAtIndex(tmpArray, index);
- files->removeAll(path);
- removePathFromHash(filePathInfoHash, cfpath, path);
- } else {
- // Could be a directory we are watching instead.
- QCFString cfdirpath(createFSStreamPath(fi.canonicalFilePath()));
- index = CFArrayGetFirstIndexOfValue(tmpArray, CFRangeMake(0, itemCount), cfdirpath);
- if (index != -1) {
- CFArrayRemoveValueAtIndex(tmpArray, index);
- directories->removeAll(path);
- removePathFromHash(dirPathInfoHash, cfpath, path);
- } else {
- failedToRemove.append(path);
- }
- }
- }
- itemCount = CFArrayGetCount(tmpArray);
- if (itemCount != 0) {
- pathsToWatch = CFArrayCreateCopy(kCFAllocatorDefault, tmpArray);
-
- FSEventStreamContext context = { 0, this, 0, 0, 0 };
- fsStream = FSEventStreamCreate(kCFAllocatorDefault,
- QFSEventsFileSystemWatcherEngine::fseventsCallback,
- &context, pathsToWatch, idToCheck, Latency, QtFSEventFlags);
- warmUpFSEvents();
- }
- return failedToRemove;
-#else
- Q_UNUSED(paths);
- Q_UNUSED(files);
- Q_UNUSED(directories);
- return QStringList();
-#endif
-}
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-void QFSEventsFileSystemWatcherEngine::updateList(PathInfoList &list, bool directory, bool emitSignals)
-{
- PathInfoList::iterator End = list.end();
- PathInfoList::iterator it = list.begin();
- while (it != End) {
- struct ::stat newInfo;
- if (::stat(it->absolutePath, &newInfo) == 0) {
- if (emitSignals) {
- if (newInfo != it->savedInfo) {
- it->savedInfo = newInfo;
- if (directory)
- emit directoryChanged(it->originalPath, false);
- else
- emit fileChanged(it->originalPath, false);
- }
- } else {
- it->savedInfo = newInfo;
- }
- } else {
- if (errno == ENOENT) {
- if (emitSignals) {
- if (directory)
- emit directoryChanged(it->originalPath, true);
- else
- emit fileChanged(it->originalPath, true);
- }
- it = list.erase(it);
- continue;
- } else {
- qWarning("%s:%d:QFSEventsFileSystemWatcherEngine: stat error on %s:%s",
- __FILE__, __LINE__, qPrintable(it->originalPath), strerror(errno));
-
- }
- }
- ++it;
- }
-}
-
-void QFSEventsFileSystemWatcherEngine::updateHash(PathHash &pathHash)
-{
- PathHash::iterator HashEnd = pathHash.end();
- PathHash::iterator it = pathHash.begin();
- const bool IsDirectory = (&pathHash == &dirPathInfoHash);
- while (it != HashEnd) {
- updateList(it.value(), IsDirectory, false);
- if (it.value().isEmpty())
- it = pathHash.erase(it);
- else
- ++it;
- }
-}
-#endif
-
-void QFSEventsFileSystemWatcherEngine::fseventsCallback(ConstFSEventStreamRef ,
- void *clientCallBackInfo, size_t numEvents,
- void *eventPaths,
- const FSEventStreamEventFlags eventFlags[],
- const FSEventStreamEventId [])
-{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- QFSEventsFileSystemWatcherEngine *watcher = static_cast<QFSEventsFileSystemWatcherEngine *>(clientCallBackInfo);
- QMutexLocker locker(&watcher->mutex);
- CFArrayRef paths = static_cast<CFArrayRef>(eventPaths);
- for (size_t i = 0; i < numEvents; ++i) {
- const QString path = QCFString::toQString(
- static_cast<CFStringRef>(CFArrayGetValueAtIndex(paths, i)));
- const FSEventStreamEventFlags pathFlags = eventFlags[i];
- // There are several flags that may be passed, but we really don't care about them ATM.
- // Here they are and why we don't care.
- // kFSEventStreamEventFlagHistoryDone--(very unlikely to be gotten, but even then, not much changes).
- // kFSEventStreamEventFlagMustScanSubDirs--Likely means the data is very much out of date, we
- // aren't coalescing our directories, so again not so much of an issue
- // kFSEventStreamEventFlagRootChanged | kFSEventStreamEventFlagMount | kFSEventStreamEventFlagUnmount--
- // These three flags indicate something has changed, but the stat will likely show this, so
- // there's not really much to worry about.
- // (btw, FSEvents is not the correct way of checking for mounts/unmounts,
- // there are real CarbonCore events for that.)
- Q_UNUSED(pathFlags);
- if (watcher->filePathInfoHash.contains(path))
- watcher->updateList(watcher->filePathInfoHash[path], false, true);
-
- if (watcher->dirPathInfoHash.contains(path))
- watcher->updateList(watcher->dirPathInfoHash[path], true, true);
- }
-#else
- Q_UNUSED(clientCallBackInfo);
- Q_UNUSED(numEvents);
- Q_UNUSED(eventPaths);
- Q_UNUSED(eventFlags);
-#endif
-}
-
-void QFSEventsFileSystemWatcherEngine::stop()
-{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- QMutexLocker locker(&mutex);
- stopFSStream(fsStream);
- if (threadsRunLoop) {
- CFRunLoopStop(threadsRunLoop);
- waitForStop.wait(&mutex);
- }
-#endif
-}
-
-void QFSEventsFileSystemWatcherEngine::updateFiles()
-{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- QMutexLocker locker(&mutex);
- updateHash(filePathInfoHash);
- updateHash(dirPathInfoHash);
- if (filePathInfoHash.isEmpty() && dirPathInfoHash.isEmpty()) {
- // Everything disappeared before we got to start, don't bother.
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- // Code duplicated from stop(), with the exception that we
- // don't wait on waitForStop here. Doing this will lead to
- // a deadlock since this function is called from the worker
- // thread. (waitForStop.wakeAll() is only called from the
- // end of run()).
- stopFSStream(fsStream);
- if (threadsRunLoop)
- CFRunLoopStop(threadsRunLoop);
-#endif
- cleanupFSStream(fsStream);
- }
- waitCondition.wakeAll();
-#endif
-}
-
-void QFSEventsFileSystemWatcherEngine::run()
-{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- threadsRunLoop = CFRunLoopGetCurrent();
- FSEventStreamScheduleWithRunLoop(fsStream, threadsRunLoop, kCFRunLoopDefaultMode);
- bool startedOK = FSEventStreamStart(fsStream);
- // It's recommended by Apple that you only update the files after you've started
- // the stream, because otherwise you might miss an update in between starting it.
- updateFiles();
-#ifdef QT_NO_DEBUG
- Q_UNUSED(startedOK);
-#else
- Q_ASSERT(startedOK);
-#endif
- // If for some reason we called stop up above (and invalidated our stream), this call will return
- // immediately.
- CFRunLoopRun();
- threadsRunLoop = 0;
- QMutexLocker locker(&mutex);
- waitForStop.wakeAll();
-#endif
-}
-
-QT_END_NAMESPACE
-#endif //QT_NO_FILESYSTEMWATCHER
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents_p.h b/src/corelib/io/qfilesystemwatcher_fsevents_p.h
deleted file mode 100644
index 311a5b55e3..0000000000
--- a/src/corelib/io/qfilesystemwatcher_fsevents_p.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef FILEWATCHER_FSEVENTS_P_H
-#define FILEWATCHER_FSEVENTS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qfilesystemwatcher_p.h"
-
-#ifndef QT_NO_FILESYSTEMWATCHER
-
-#include <QtCore/qmutex.h>
-#include <QtCore/qwaitcondition.h>
-#include <QtCore/qthread.h>
-#include <QtCore/qhash.h>
-#include <QtCore/qlinkedlist.h>
-#include <private/qcore_mac_p.h>
-#include <sys/stat.h>
-
-typedef struct __FSEventStream *FSEventStreamRef;
-typedef const struct __FSEventStream *ConstFSEventStreamRef;
-typedef const struct __CFArray *CFArrayRef;
-typedef UInt32 FSEventStreamEventFlags;
-typedef uint64_t FSEventStreamEventId;
-
-QT_BEGIN_NAMESPACE
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-// Yes, I use a stat element here. QFileInfo requires too much knowledge about implementation
-// details to be used as a long-standing record. Since I'm going to have to store this information, I can
-// do the stat myself too.
-struct PathInfo {
- PathInfo(const QString &path, const QByteArray &absPath)
- : originalPath(path), absolutePath(absPath) {}
- QString originalPath; // The path we need to emit
- QByteArray absolutePath; // The path we need to stat.
- struct ::stat savedInfo; // All the info for the path so we can compare it.
-};
-typedef QLinkedList<PathInfo> PathInfoList;
-typedef QHash<QString, PathInfoList> PathHash;
-#endif
-
-class QFSEventsFileSystemWatcherEngine : public QFileSystemWatcherEngine
-{
- Q_OBJECT
-public:
- ~QFSEventsFileSystemWatcherEngine();
-
- static QFSEventsFileSystemWatcherEngine *create();
-
- QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories);
- QStringList removePaths(const QStringList &paths, QStringList *files, QStringList *directories);
-
- void stop();
-
-private:
- QFSEventsFileSystemWatcherEngine();
- void warmUpFSEvents();
- void updateFiles();
-
- static void fseventsCallback(ConstFSEventStreamRef streamRef, void *clientCallBackInfo, size_t numEvents,
- void *eventPaths, const FSEventStreamEventFlags eventFlags[],
- const FSEventStreamEventId eventIds[]);
- void run();
- FSEventStreamRef fsStream;
- CFArrayRef pathsToWatch;
- CFRunLoopRef threadsRunLoop;
- QMutex mutex;
- QWaitCondition waitCondition;
- QWaitCondition waitForStop;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- PathHash filePathInfoHash;
- PathHash dirPathInfoHash;
- void updateHash(PathHash &pathHash);
- void updateList(PathInfoList &list, bool directory, bool emitSignals);
-#endif
-};
-
-#endif //QT_NO_FILESYSTEMWATCHER
-
-#endif
-
-QT_END_NAMESPACE