From 138a060df22a6bb962bebe4b8470b53a4039f0da Mon Sep 17 00:00:00 2001 From: Daniel Molkentin Date: Thu, 6 Dec 2012 16:26:27 +0100 Subject: Fix Windows folder watcher --- src/mirall/folderwatcher.cpp | 2 +- src/mirall/folderwatcher.h | 4 +--- src/mirall/folderwatcher_win.cpp | 43 ++++++++++++++++++++++++++++------------ src/mirall/folderwatcher_win.h | 9 +++++++-- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/mirall/folderwatcher.cpp b/src/mirall/folderwatcher.cpp index d98488f19..ef60ab9cb 100644 --- a/src/mirall/folderwatcher.cpp +++ b/src/mirall/folderwatcher.cpp @@ -163,7 +163,7 @@ void FolderWatcher::setProcessTimer() _processTimer->start(eventInterval()); } -void FolderWatcher::changeDetected(QString f) +void FolderWatcher::changeDetected(const QString& f) { if( ! eventsEnabled() ) { qDebug() << "FolderWatcher::changeDetected when eventsEnabled() -> ignore"; diff --git a/src/mirall/folderwatcher.h b/src/mirall/folderwatcher.h index 6b115bae9..494040f36 100644 --- a/src/mirall/folderwatcher.h +++ b/src/mirall/folderwatcher.h @@ -112,12 +112,10 @@ protected: protected slots: // called when the manually process timer triggers void slotProcessTimerTimeout(); + void changeDetected(const QString &f); - // TODO: this belongs with the inotify backend protected: QHash _pendingPathes; - friend class FolderWatcherPrivate; - private: bool _eventsEnabled; diff --git a/src/mirall/folderwatcher_win.cpp b/src/mirall/folderwatcher_win.cpp index 46a27c7b6..992065828 100644 --- a/src/mirall/folderwatcher_win.cpp +++ b/src/mirall/folderwatcher_win.cpp @@ -18,7 +18,6 @@ #include "mirall/folderwatcher.h" #include "mirall/folderwatcher_win.h" -#include #include #include #include @@ -27,47 +26,65 @@ namespace Mirall { void WatcherThread::run() { - HANDLE handle; - - handle = FindFirstChangeNotification((wchar_t*)_path.utf16(), + _handle = FindFirstChangeNotification((wchar_t*)_path.utf16(), true, // recursive watch FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE); - if (handle == INVALID_HANDLE_VALUE) + if (_handle == INVALID_HANDLE_VALUE) { - printf("\n ERROR: FindFirstChangeNotification function failed.\n"); + qDebug() << Q_FUNC_INFO << "FindFirstChangeNotification function failed, stopping watcher!"; + FindCloseChangeNotification(_handle); + _handle = 0; return; } - if (handle == NULL) + if (_handle == NULL) { - printf("\n ERROR: FindFirstChangeNotification returned null.\n"); + qDebug() << Q_FUNC_INFO << "FindFirstChangeNotification returned null, stopping watcher!"; + FindCloseChangeNotification(_handle); + _handle = 0; return; } while(true) { - switch(WaitForSingleObject(handle, /*wait*/ INFINITE)) { + switch(WaitForSingleObject(_handle, /*wait*/ INFINITE)) { case WAIT_OBJECT_0: - emit changed(); + if (FindNextChangeNotification(_handle) == false) { + qDebug() << Q_FUNC_INFO << "FindFirstChangeNotification returned FALSE, stopping watcher!"; + FindCloseChangeNotification(_handle); + _handle = 0; + return; + } + qDebug() << Q_FUNC_INFO << "Change detected in" << _path << "from" << QThread::currentThread (); + emit changed(_path); break; default: - qDebug() << "Error while watching"; + qDebug() << Q_FUNC_INFO << "Error while watching"; } } } -// watcher thread + +WatcherThread::~WatcherThread() +{ + if (_handle) + FindCloseChangeNotification(_handle); +} FolderWatcherPrivate::FolderWatcherPrivate(FolderWatcher *p) : _parent(p) { _thread = new WatcherThread(p->root()); - _thread->run(); + connect(_thread, SIGNAL(changed(const QString&)), + _parent,SLOT(changeDetected(const QString&))); + _thread->start(); } FolderWatcherPrivate::~FolderWatcherPrivate() { + _thread->terminate(); + _thread->wait(); delete _thread; } diff --git a/src/mirall/folderwatcher_win.h b/src/mirall/folderwatcher_win.h index f8dc5b9dc..85c728bd7 100644 --- a/src/mirall/folderwatcher_win.h +++ b/src/mirall/folderwatcher_win.h @@ -16,6 +16,7 @@ #define MIRALL_FOLDERWATCHER_WIN_H #include +#include namespace Mirall { @@ -27,15 +28,19 @@ class WatcherThread : public QThread { Q_OBJECT public: WatcherThread(const QString &path) : - QThread(), _path(path) {} + QThread(), _path(path), _handle(0) {} + ~WatcherThread(); + +protected: void run(); signals: - void changed(); + void changed(const QString &path); private: QString _path; + HANDLE _handle; }; class FolderWatcherPrivate : public QObject { -- cgit v1.2.3