FolderWatcher: Wait for ready before testing #7305
authorChristian Kamm <mail@ckamm.de>
Thu, 11 Jul 2019 11:31:54 +0000 (13:31 +0200)
committerCamila (Rebase PR Action) <hello@camila.codes>
Tue, 24 Nov 2020 16:56:49 +0000 (16:56 +0000)
src/gui/folderwatcher.cpp
src/gui/folderwatcher.h
src/gui/folderwatcher_linux.h
src/gui/folderwatcher_mac.h
src/gui/folderwatcher_win.cpp
src/gui/folderwatcher_win.h

index 6151b1116edb1d89416ab20927e2f00aefbdf7f6..80685e3cf626a2c6eba3aa3917122ff8389d1f58 100644 (file)
@@ -92,6 +92,19 @@ void FolderWatcher::startNotificatonTest(const QString &path)
     Q_ASSERT(_testNotificationPath.isEmpty());
     _testNotificationPath = path;
 
+    // Don't do the local file modification immediately:
+    // wait for FolderWatchPrivate::_ready
+    startNotificationTestWhenReady();
+}
+
+void FolderWatcher::startNotificationTestWhenReady()
+{
+    if (!_d->_ready) {
+        QTimer::singleShot(1000, this, &FolderWatcher::startNotificationTestWhenReady);
+        return;
+    }
+
+    auto path = _testNotificationPath;
     if (QFile::exists(path)) {
         auto mtime = FileSystem::getModTime(path);
         FileSystem::setModTime(path, mtime + 1);
@@ -100,13 +113,14 @@ void FolderWatcher::startNotificatonTest(const QString &path)
         f.open(QIODevice::WriteOnly | QIODevice::Append);
     }
 
-    QTimer::singleShot(5000, this, [&]() {
+    QTimer::singleShot(5000, this, [this]() {
         if (!_testNotificationPath.isEmpty())
             emit becameUnreliable(tr("The watcher did not receive a test notification."));
         _testNotificationPath.clear();
     });
 }
 
+
 int FolderWatcher::testLinuxWatchCount() const
 {
 #ifdef Q_OS_LINUX
index ef1a7c39478ba1acb0eedbc7479b34c1ddfb766e..f7d75fcc42c3d35f8a5f84f9d461592b6c8b7c61 100644 (file)
@@ -109,6 +109,9 @@ protected slots:
     void changeDetected(const QString &path);
     void changeDetected(const QStringList &paths);
 
+private slots:
+    void startNotificationTestWhenReady();
+
 protected:
     QHash<QString, int> _pendingPathes;
 
index ba651f7005df20847692ffc6614995bf8a0f9df3..277736b40b0d27876e823e662553e4f4ef41601b 100644 (file)
@@ -41,6 +41,9 @@ public:
 
     int testWatchCount() const { return _pathToWatch.size(); }
 
+    /// On linux the watcher is ready when the ctor finished.
+    bool _ready = true;
+
 protected slots:
     void slotReceivedNotification(int fd);
     void slotAddFolderRecursive(const QString &path);
index 4ec666945d6385aad0a6f2825a27026381ef7459..e68124f824326b2e637f01042cad623dc44392e2 100644 (file)
@@ -37,6 +37,9 @@ public:
     QStringList addCoalescedPaths(const QStringList &) const;
     void doNotifyParent(const QStringList &);
 
+    /// On OSX the watcher is ready when the ctor finished.
+    bool _ready = true;
+
 private:
     FolderWatcher *_parent;
 
index 4907b5adfb1c20c5a3108f54dcf887ddb127bdc5..8799431a101ba56f93388003666caf994b8678be 100644 (file)
@@ -84,6 +84,8 @@ void WatcherThread::watchChanges(size_t fileNotifyBufferSize,
             break;
         }
 
+        emit ready();
+
         HANDLE handles[] = { _resultEvent, _stopEvent };
         DWORD result = WaitForMultipleObjects(
             2, handles,
@@ -204,6 +206,8 @@ FolderWatcherPrivate::FolderWatcherPrivate(FolderWatcher *p, const QString &path
         _parent, SLOT(changeDetected(const QString &)));
     connect(_thread, SIGNAL(lostChanges()),
         _parent, SIGNAL(lostChanges()));
+    connect(_thread, &WatcherThread::ready,
+        this, [this]() { _ready = 1; });
     _thread->start();
 }
 
index a556e91466ea090a7c0b8a779681578b7ae29474..c89bfbbae897db5f0bb3a6a42922e890ba82654d 100644 (file)
@@ -54,6 +54,7 @@ protected:
 signals:
     void changed(const QString &path);
     void lostChanges();
+    void ready();
 
 private:
     QString _path;
@@ -74,6 +75,9 @@ public:
     FolderWatcherPrivate(FolderWatcher *p, const QString &path);
     ~FolderWatcherPrivate();
 
+    /// Set to non-zero once the WatcherThread is capturing events.
+    QAtomicInt _ready;
+
 private:
     FolderWatcher *_parent;
     WatcherThread *_thread;