Remove OS X FSEvents watcher.
authorRobin Burchell <robin.burchell@collabora.com>
Tue, 3 Jan 2012 20:31:08 +0000 (21:31 +0100)
committerQt by Nokia <qt-info@nokia.com>
Thu, 5 Jan 2012 13:35:59 +0000 (14:35 +0100)
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>
src/corelib/io/io.pri
src/corelib/io/qfilesystemwatcher.cpp
src/corelib/io/qfilesystemwatcher_fsevents.cpp [deleted file]
src/corelib/io/qfilesystemwatcher_fsevents_p.h [deleted file]

index 380714e..d7eb710 100644 (file)
@@ -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
index 4e9ac9b..580239d 100644 (file)
@@ -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 (file)
index 8f7094f..0000000
+++ /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 (file)
index 311a5b5..0000000
+++ /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