Fall back to polling in autorevert when needed
* lisp/autorevert.el (auto-revert-notify-handler): When a `stopped' event arrives from file notification, fall back to polling. * test/automated/file-notify-tests.el (file-notify-test03-autorevert): Extend test for polling when file notification ceases to work.
This commit is contained in:
parent
99ded6be7a
commit
838023d469
2 changed files with 74 additions and 30 deletions
|
@ -570,37 +570,54 @@ no more reverts are possible until the next call of
|
|||
;; Since we watch a directory, a file name must be returned.
|
||||
(cl-assert (stringp file))
|
||||
(when (eq action 'renamed) (cl-assert (stringp file1)))
|
||||
;; Loop over all buffers, in order to find the intended one.
|
||||
(cl-dolist (buffer buffers)
|
||||
(when (buffer-live-p buffer)
|
||||
(with-current-buffer buffer
|
||||
(when (or
|
||||
;; A buffer associated with a file.
|
||||
(and (stringp buffer-file-name)
|
||||
(or
|
||||
(and (memq action '(attribute-changed changed created))
|
||||
(string-equal
|
||||
(file-name-nondirectory file)
|
||||
(file-name-nondirectory buffer-file-name)))
|
||||
(and (eq action 'renamed)
|
||||
(string-equal
|
||||
(file-name-nondirectory file1)
|
||||
(file-name-nondirectory buffer-file-name)))))
|
||||
;; A buffer w/o a file, like dired.
|
||||
(and (null buffer-file-name)
|
||||
(memq action '(created renamed deleted))))
|
||||
;; Mark buffer modified.
|
||||
(setq auto-revert-notify-modified-p t)
|
||||
|
||||
;; Revert the buffer now if we're not locked out.
|
||||
(when (/= auto-revert-buffers-counter-lockedout
|
||||
auto-revert-buffers-counter)
|
||||
(auto-revert-handler)
|
||||
(setq auto-revert-buffers-counter-lockedout
|
||||
auto-revert-buffers-counter))
|
||||
(if (eq action 'stopped)
|
||||
;; File notification has stopped. Continue with polling.
|
||||
(cl-dolist (buffer buffers)
|
||||
(with-current-buffer buffer
|
||||
(when (or
|
||||
;; A buffer associated with a file.
|
||||
(and (stringp buffer-file-name)
|
||||
(string-equal
|
||||
(file-name-nondirectory file)
|
||||
(file-name-nondirectory buffer-file-name)))
|
||||
;; A buffer w/o a file, like dired.
|
||||
(null buffer-file-name))
|
||||
(auto-revert-notify-rm-watch)
|
||||
(setq-local auto-revert-use-notify nil))))
|
||||
|
||||
;; No need to check other buffers.
|
||||
(cl-return))))))))
|
||||
;; Loop over all buffers, in order to find the intended one.
|
||||
(cl-dolist (buffer buffers)
|
||||
(when (buffer-live-p buffer)
|
||||
(with-current-buffer buffer
|
||||
(when (or
|
||||
;; A buffer associated with a file.
|
||||
(and (stringp buffer-file-name)
|
||||
(or
|
||||
(and (memq
|
||||
action '(attribute-changed changed created))
|
||||
(string-equal
|
||||
(file-name-nondirectory file)
|
||||
(file-name-nondirectory buffer-file-name)))
|
||||
(and (eq action 'renamed)
|
||||
(string-equal
|
||||
(file-name-nondirectory file1)
|
||||
(file-name-nondirectory buffer-file-name)))))
|
||||
;; A buffer w/o a file, like dired.
|
||||
(and (null buffer-file-name)
|
||||
(memq action '(created renamed deleted))))
|
||||
;; Mark buffer modified.
|
||||
(setq auto-revert-notify-modified-p t)
|
||||
|
||||
;; Revert the buffer now if we're not locked out.
|
||||
(when (/= auto-revert-buffers-counter-lockedout
|
||||
auto-revert-buffers-counter)
|
||||
(auto-revert-handler)
|
||||
(setq auto-revert-buffers-counter-lockedout
|
||||
auto-revert-buffers-counter))
|
||||
|
||||
;; No need to check other buffers.
|
||||
(cl-return)))))))))
|
||||
|
||||
(defun auto-revert-active-p ()
|
||||
"Check if auto-revert is active (in current buffer or globally)."
|
||||
|
|
|
@ -461,6 +461,8 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered."
|
|||
|
||||
;; Modify file. We wait for a second, in order to
|
||||
;; have another timestamp.
|
||||
(with-current-buffer (get-buffer-create "*Messages*")
|
||||
(narrow-to-region (point-max) (point-max)))
|
||||
(sleep-for 1)
|
||||
(write-region
|
||||
"another text" nil file-notify--test-tmpfile nil 'no-message)
|
||||
|
@ -472,9 +474,34 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered."
|
|||
(string-match
|
||||
(format-message "Reverting buffer `%s'." (buffer-name buf))
|
||||
(buffer-string))))
|
||||
(should (string-match "another text" (buffer-string)))))
|
||||
(should (string-match "another text" (buffer-string)))
|
||||
|
||||
;; Stop file notification. Autorevert shall still work via polling.
|
||||
(file-notify-rm-watch auto-revert-notify-watch-descriptor)
|
||||
(file-notify--wait-for-events
|
||||
timeout (null auto-revert-use-notify))
|
||||
(should-not auto-revert-use-notify)
|
||||
(should-not auto-revert-notify-watch-descriptor)
|
||||
|
||||
;; Modify file. We wait for a second, in order to
|
||||
;; have another timestamp.
|
||||
(with-current-buffer (get-buffer-create "*Messages*")
|
||||
(narrow-to-region (point-max) (point-max)))
|
||||
(sleep-for 2)
|
||||
(write-region
|
||||
"foo bla" nil file-notify--test-tmpfile nil 'no-message)
|
||||
|
||||
;; Check, that the buffer has been reverted.
|
||||
(with-current-buffer (get-buffer-create "*Messages*")
|
||||
(file-notify--wait-for-events
|
||||
timeout
|
||||
(string-match
|
||||
(format-message "Reverting buffer `%s'." (buffer-name buf))
|
||||
(buffer-string))))
|
||||
(should (string-match "foo bla" (buffer-string)))))
|
||||
|
||||
;; Cleanup.
|
||||
(with-current-buffer "*Messages*" (widen))
|
||||
(ignore-errors (kill-buffer buf))
|
||||
(file-notify--test-cleanup))))
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue