Le 11/05/2017 à 09:59, Stephan Witt a écrit :

The delay is defined in Buffer::Impl::blockFileMonitor (Buffer.cpp:388)
currently at 10ms. Can you try to increase this value and see if that
helps? It will likely help, but this is not a nice solution.

I tried it with a delay of 100ms. The effect is now LyX presents the external
modification message box every 2nd or 3rd save. So it is not the solution.

Thanks for the test, this helps. BTW is there a delay before the message
appears and if so how long? Do you see the following error message with
the files debug flag:
  LYXERR(Debug::FILES, "Could not add path to QFileSystemWatcher: " <<
filename_);
?



Ideally I would like to have everything work with a delay of 0ms, to be
sure that everyone experiences the same. Can you help me and see if it
is possible to flush the file operations in FileName::copyTo and
FileName::moveTo and if it makes a difference ? There is QFile::flush
but I do not really see how to use it in this context and I cannot test
the situation.

I cannot see how to do it here.

The save operation in this scenario is done with one create (temp), one
rename (backup) and another rename (final name).

Are you sure the file monitor is able to follow these steps?

What is expected to happen is:

In Buffer::save:

1. Disconnect from QFileSystemWatcher
2. Perform various file operations
3. Queue the reconnection to QFileSystemWatcher

Later:

4. QFileSystemWatcher notifies of the deletion
5. The new file is moved
6. Reconnect to QFileSystemWatcher and refresh (watch the new file)

Given the behaviour that you report above, it seems that the
reconnection happens too early. The number and the nature of the
operations is not important.

I notice that the QSaveFile class which is provided by Qt (but not used
in LyX) calls a function fileEngine->syncToDisk() not accessible from
the API, and below there are the comments:
// atomically replace old file with new file
// Can't use QFile::rename for that, must use the file engine directly

I suspect that using QSaveFile instead of the current implementation
would solve the bug and make file saving safer (even).

Can you please try the attached patch? Before deciding which solution is
the best I will still need to know the answer to the questions at the
beginning, if you please can help with that.

Thank you
Guillaume

>From 17f644c2cc1c21020aa71215762941930689f951 Mon Sep 17 00:00:00 2001
From: Guillaume MM <g...@lyx.org>
Date: Sat, 13 May 2017 01:00:30 +0200
Subject: [PATCH] Prevent false positives in external modifications

When the Buffer is notified to be externally modified, check that the
file contents have changed using the checksum.
---
 src/Buffer.cpp | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index 239bacd..60619dc 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -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.
@@ -5340,8 +5340,11 @@ void Buffer::Impl::refreshFileMonitor()
 
 void Buffer::Impl::fileExternallyModified(bool modified) const
 {
-	if (modified)
+	if (modified) {
+		if (filename.exists() && checksum_ == filename.checksum())
+			return;
 		lyx_clean = bak_clean = false;
+	}
 	externally_modified_ = modified;
 	if (wa_)
 		wa_->updateTitles();
-- 
2.7.4

Reply via email to