]> git.lyx.org Git - lyx.git/commitdiff
Prevent false positives in external modifications
authorGuillaume MM <gm@lyx.org>
Fri, 12 May 2017 23:00:30 +0000 (01:00 +0200)
committerGuillaume MM <gm@lyx.org>
Sun, 11 Jun 2017 17:51:17 +0000 (19:51 +0200)
When the Buffer is notified to be externally modified, check that the
file contents have changed using the checksum.

Document the shortcoming of FileMonitorBlocker.

Fixes #10642.

src/Buffer.cpp
src/support/FileMonitor.h

index 9f6b20f7b7da9530178528545eb9f9508660b3d1..9eded216f1f32daa5203f5344a3b75ba3cf29bc9 100644 (file)
@@ -386,7 +386,7 @@ public:
        void fileExternallyModified(bool modified) const;
 
        /// Block notifications of external modifications
-       FileMonitorBlocker blockFileMonitor() { return file_monitor_->block(10); }
+       FileMonitorBlocker blockFileMonitor() { return file_monitor_->block(); }
 
 private:
        /// So we can force access via the accessors.
@@ -5341,8 +5341,16 @@ void Buffer::Impl::refreshFileMonitor()
 
 void Buffer::Impl::fileExternallyModified(bool modified) const
 {
-       if (modified)
+       if (modified) {
+               // prevent false positives, because FileMonitorBlocker is not enough on
+               // OSX.
+               if (filename.exists() && checksum_ == filename.checksum()) {
+                       LYXERR(Debug::FILES, "External modification but "
+                              "checksum unchanged: " << filename);
+                       return;
+               }
                lyx_clean = bak_clean = false;
+       }
        externally_modified_ = modified;
        if (wa_)
                wa_->updateTitles();
index 49f12cba7271a0084d41fa9f1a0cfc63918752cd..5e516bb01283bfdb6f5d8869237c13ade3cd50cf 100644 (file)
@@ -167,11 +167,18 @@ public:
        /// absolute path being tracked
        std::string const & filename() { return monitor_->filename(); }
        /// Creates a guard that blocks notifications. Copyable. Notifications from
-       /// this monitor are blocked as long as there are copies around.
+       /// this monitor are blocked as long as there are copies of the
+       /// FileMonitorBlocker around.
        /// \param delay is the amount waited in ms after expiration of the guard
-       /// before reconnecting. This delay thing is to deal with asynchronous
-       /// notifications in a not so elegant fashion. But it can also be used to
-       /// slow down incoming events.
+       /// before reconnecting. It can be used to slow down incoming events
+       /// accordingly. A value of 0 is still made asynchronous, because of the
+       /// fundamentally asynchronous nature of QFileSystemWatcher. To catch one's
+       /// own file operations, a value of 0 for delay is sufficient with the
+       /// inotify backend (e.g. Linux); for OSX (kqueue), a value of 100ms is
+       /// unsufficient and more tests need to be done in combination with
+       /// flushing/syncing to disk in order to understand how to catch one's own
+       /// operations reliably. No feedback from Windows yet. See
+       /// <https://www.mail-archive.com/lyx-devel@lists.lyx.org/msg200252.html>.
        FileMonitorBlocker block(int delay = 0);
        /// Make sure the good file is being monitored, after e.g. a move or a
        /// deletion. See <https://bugreports.qt.io/browse/QTBUG-46483>. This is