emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master e5a74c2: Make multisession file reading more resilient on Windows


From: Lars Ingebrigtsen
Subject: master e5a74c2: Make multisession file reading more resilient on Windows
Date: Sat, 18 Dec 2021 03:24:27 -0500 (EST)

branch: master
commit e5a74c20c399cdcab6115197da4b96eec8d3a345
Author: Lars Ingebrigtsen <larsi@gnus.org>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    Make multisession file reading more resilient on Windows
    
    * lisp/emacs-lisp/multisession.el (multisession--read-file-value):
    Rename and try harder on file errors on Windows.
---
 lisp/emacs-lisp/multisession.el | 45 ++++++++++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/lisp/emacs-lisp/multisession.el b/lisp/emacs-lisp/multisession.el
index bce888a..6ef0da1 100644
--- a/lisp/emacs-lisp/multisession.el
+++ b/lisp/emacs-lisp/multisession.el
@@ -250,23 +250,30 @@ DOC should be a doc string, and ARGS are keywords as 
applicable to
 (defun multisession--encode-file-name (name)
   (url-hexify-string name))
 
-(defun multisession--update-file-value (file object)
-  (condition-case nil
-      (with-temp-buffer
-        (let* ((time (file-attribute-modification-time
-                      (file-attributes file)))
-               (coding-system-for-read 'utf-8))
-          (insert-file-contents file)
-          (let ((stored (read (current-buffer))))
-            (setf (multisession--cached-value object) stored
-                  (multisession--cached-sequence object) time)
-            stored)))
-    ;; If the file is contended (could happen with file locking in
-    ;; Windws) or unreadable, just return the current value.
-    (error
-     (if (eq (multisession--cached-value object) multisession--unbound)
-         (multisession--initial-value object)
-       (multisession--cached-value object)))))
+(defun multisession--read-file-value (file object)
+  (catch 'done
+    (let ((i 0)
+          last-error)
+      (while (< i 10)
+        (condition-case err
+            (throw 'done
+                   (with-temp-buffer
+                     (let* ((time (file-attribute-modification-time
+                                   (file-attributes file)))
+                            (coding-system-for-read 'utf-8))
+                       (insert-file-contents file)
+                       (let ((stored (read (current-buffer))))
+                         (setf (multisession--cached-value object) stored
+                               (multisession--cached-sequence object) time)
+                         stored))))
+          ;; Windows uses OS-level file locking that may preclude
+          ;; reading the file in some circumstances.  So when that
+          ;; happens, wait a bit and try again.
+          (file-error
+           (setq i (1+ i)
+                 last-error err)
+           (sleep-for (+ 0.1 (/ (float (random 10)) 10))))))
+      (signal (car last-error) (cdr last-error)))))
 
 (defun multisession--object-file-name (object)
   (expand-file-name
@@ -283,7 +290,7 @@ DOC should be a doc string, and ARGS are keywords as 
applicable to
      ;; We have no value yet; see whether it's stored.
      ((eq (multisession--cached-value object) multisession--unbound)
       (if (file-exists-p file)
-          (multisession--update-file-value file object)
+          (multisession--read-file-value file object)
         ;; Nope; return the initial value.
         (multisession--initial-value object)))
      ;; We have a value, but we want to update in case some other
@@ -293,7 +300,7 @@ DOC should be a doc string, and ARGS are keywords as 
applicable to
                (time-less-p (multisession--cached-sequence object)
                             (file-attribute-modification-time
                              (file-attributes file))))
-          (multisession--update-file-value file object)
+          (multisession--read-file-value file object)
         ;; Nothing, return the cached value.
         (multisession--cached-value object)))
      ;; Just return the cached value.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]