mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-04 11:40:22 +00:00
Fix Bug#22814
* lisp/autorevert.el (global-auto-revert-mode): Do not set `auto-revert-use-notify' to nil. * etc/NEWS: Mention this. * etc/PROBLEMS: Remove problem Bug#22814. * src/kqueue.c: Include <sys/resource.h>. (Fkqueue_add_watch): Limit the number of used file descriptors. (Bug#22814) * test/lisp/filenotify-tests.el (file-notify--test-remote-enabled) (file-notify-test00-availability, file-notify-test01-add-watch) (file-notify-test02-events, file-notify-test06-many-events): Use #' read syntax for functions. (file-notify-test05-dir-validity) (file-notify-test06-many-events): Simplify directory creation. (file-notify-test09-sufficient-ressources): New test.
This commit is contained in:
parent
ca4e30058e
commit
4849677967
3
etc/NEWS
3
etc/NEWS
@ -114,6 +114,9 @@ different group ID.
|
||||
+++
|
||||
*** New connection method "doas" for OpenBSD hosts.
|
||||
|
||||
---
|
||||
** `auto-revert-use-notify' is set back to t in `global-auto-revert-mode'.
|
||||
|
||||
|
||||
* New Modes and Packages in Emacs 25.2
|
||||
|
||||
|
11
etc/PROBLEMS
11
etc/PROBLEMS
@ -600,17 +600,6 @@ you have a personal configuration file (normally ~/.aspell.conf), it
|
||||
can cause this error. Remove that file, execute 'ispell-kill-ispell'
|
||||
in Emacs, and then try spell-checking again.
|
||||
|
||||
*** Emacs eats all file descriptors when using kqueue file notifications.
|
||||
See <http://debbugs.gnu.org/22814>.
|
||||
|
||||
When you have a large number of buffers running auto-revert-mode, and
|
||||
Emacs is configured to use the kqueue file notification library, it
|
||||
uses an own file descriptor for every watched file. On systems with a
|
||||
small limit of file descriptors allowed per process, like OS X, you
|
||||
could run out of file descriptors. You won't be able to open new files.
|
||||
|
||||
auto-revert-use-notify is set to nil in global-auto-revert-mode, therefore.
|
||||
|
||||
* Runtime problems related to font handling
|
||||
|
||||
** Characters are displayed as empty boxes or with wrong font under X.
|
||||
|
@ -458,11 +458,7 @@ specifies in the mode line."
|
||||
:global t :group 'auto-revert :lighter global-auto-revert-mode-text
|
||||
(auto-revert-set-timer)
|
||||
(if global-auto-revert-mode
|
||||
(progn
|
||||
;; We disable file notification because it could use too many
|
||||
;; ressources. See <http://debbugs.gnu.org/22814>.
|
||||
(setq auto-revert-use-notify nil)
|
||||
(auto-revert-buffers))
|
||||
(auto-revert-buffers)
|
||||
(dolist (buf (buffer-list))
|
||||
(with-current-buffer buf
|
||||
(when auto-revert-use-notify
|
||||
|
24
src/kqueue.c
24
src/kqueue.c
@ -29,6 +29,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include "keyboard.h"
|
||||
#include "process.h"
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif /* HAVE_SYS_RESOURCE_H */
|
||||
|
||||
|
||||
/* File handle for kqueue. */
|
||||
static int kqueuefd = -1;
|
||||
@ -368,9 +372,12 @@ only when the upper directory of the renamed file is watched. */)
|
||||
(Lisp_Object file, Lisp_Object flags, Lisp_Object callback)
|
||||
{
|
||||
Lisp_Object watch_object, dir_list;
|
||||
int fd, oflags;
|
||||
int maxfd, fd, oflags;
|
||||
u_short fflags = 0;
|
||||
struct kevent kev;
|
||||
#ifdef HAVE_GETRLIMIT
|
||||
struct rlimit rlim;
|
||||
#endif /* HAVE_GETRLIMIT */
|
||||
|
||||
/* Check parameters. */
|
||||
CHECK_STRING (file);
|
||||
@ -383,6 +390,21 @@ only when the upper directory of the renamed file is watched. */)
|
||||
if (! FUNCTIONP (callback))
|
||||
wrong_type_argument (Qinvalid_function, callback);
|
||||
|
||||
/* Check available file descriptors. */
|
||||
#ifdef HAVE_GETRLIMIT
|
||||
if (! getrlimit (RLIMIT_NOFILE, &rlim))
|
||||
maxfd = rlim.rlim_cur;
|
||||
else
|
||||
#endif /* HAVE_GETRLIMIT */
|
||||
maxfd = 256;
|
||||
|
||||
/* We assume 50 file descriptors are sufficient for the rest of Emacs. */
|
||||
if ((maxfd - 50) < XINT (Flength (watch_list)))
|
||||
xsignal2
|
||||
(Qfile_notify_error,
|
||||
build_string ("File watching not possible, no file descriptor left"),
|
||||
Flength (watch_list));
|
||||
|
||||
if (kqueuefd < 0)
|
||||
{
|
||||
/* Create kqueue descriptor. */
|
||||
|
@ -140,7 +140,7 @@ being the result.")
|
||||
(setq desc
|
||||
(file-notify-add-watch
|
||||
file-notify-test-remote-temporary-file-directory
|
||||
'(change) 'ignore))))
|
||||
'(change) #'ignore))))
|
||||
(setq file-notify--test-remote-enabled-checked (cons t desc))
|
||||
(when desc (file-notify-rm-watch desc))))
|
||||
;; Return result.
|
||||
@ -180,7 +180,7 @@ remote host, or nil."
|
||||
(message "Library: `%s'" (file-notify--test-library))
|
||||
(should
|
||||
(setq file-notify--test-desc
|
||||
(file-notify-add-watch temporary-file-directory '(change) 'ignore)))
|
||||
(file-notify-add-watch temporary-file-directory '(change) #'ignore)))
|
||||
|
||||
;; Cleanup.
|
||||
(file-notify--test-cleanup))
|
||||
@ -199,23 +199,23 @@ remote host, or nil."
|
||||
;; Check, that different valid parameters are accepted.
|
||||
(should
|
||||
(setq file-notify--test-desc
|
||||
(file-notify-add-watch temporary-file-directory '(change) 'ignore)))
|
||||
(file-notify-add-watch temporary-file-directory '(change) #'ignore)))
|
||||
(file-notify-rm-watch file-notify--test-desc)
|
||||
(should
|
||||
(setq file-notify--test-desc
|
||||
(file-notify-add-watch
|
||||
temporary-file-directory '(attribute-change) 'ignore)))
|
||||
temporary-file-directory '(attribute-change) #'ignore)))
|
||||
(file-notify-rm-watch file-notify--test-desc)
|
||||
(should
|
||||
(setq file-notify--test-desc
|
||||
(file-notify-add-watch
|
||||
temporary-file-directory '(change attribute-change) 'ignore)))
|
||||
temporary-file-directory '(change attribute-change) #'ignore)))
|
||||
(file-notify-rm-watch file-notify--test-desc)
|
||||
(write-region "any text" nil file-notify--test-tmpfile nil 'no-message)
|
||||
(should
|
||||
(setq file-notify--test-desc
|
||||
(file-notify-add-watch
|
||||
file-notify--test-tmpfile '(change attribute-change) 'ignore)))
|
||||
file-notify--test-tmpfile '(change attribute-change) #'ignore)))
|
||||
(file-notify-rm-watch file-notify--test-desc)
|
||||
(delete-file file-notify--test-tmpfile)
|
||||
|
||||
@ -238,7 +238,7 @@ remote host, or nil."
|
||||
(should
|
||||
(equal (should-error
|
||||
(file-notify-add-watch
|
||||
file-notify--test-tmpfile1 '(change attribute-change) 'ignore))
|
||||
file-notify--test-tmpfile1 '(change attribute-change) #'ignore))
|
||||
`(file-notify-error
|
||||
"Directory does not exist" ,file-notify--test-tmpfile)))
|
||||
|
||||
@ -361,7 +361,7 @@ longer than timeout seconds for the events to be delivered."
|
||||
(setq file-notify--test-desc
|
||||
(file-notify-add-watch
|
||||
file-notify--test-tmpfile
|
||||
'(change) 'file-notify--test-event-handler)))
|
||||
'(change) #'file-notify--test-event-handler)))
|
||||
(file-notify--test-with-events
|
||||
(cond
|
||||
;; cygwin recognizes only `deleted' and `stopped' events.
|
||||
@ -381,7 +381,7 @@ longer than timeout seconds for the events to be delivered."
|
||||
(setq file-notify--test-desc
|
||||
(file-notify-add-watch
|
||||
file-notify--test-tmpfile
|
||||
'(change) 'file-notify--test-event-handler)))
|
||||
'(change) #'file-notify--test-event-handler)))
|
||||
(file-notify--test-with-events
|
||||
(cond
|
||||
;; cygwin recognizes only `deleted' and `stopped' events.
|
||||
@ -414,7 +414,7 @@ longer than timeout seconds for the events to be delivered."
|
||||
file-notify--test-desc
|
||||
(file-notify-add-watch
|
||||
temporary-file-directory
|
||||
'(change) 'file-notify--test-event-handler)))
|
||||
'(change) #'file-notify--test-event-handler)))
|
||||
(file-notify--test-with-events
|
||||
(cond
|
||||
;; w32notify does not raise `deleted' and `stopped'
|
||||
@ -445,7 +445,7 @@ longer than timeout seconds for the events to be delivered."
|
||||
file-notify--test-desc
|
||||
(file-notify-add-watch
|
||||
temporary-file-directory
|
||||
'(change) 'file-notify--test-event-handler)))
|
||||
'(change) #'file-notify--test-event-handler)))
|
||||
(file-notify--test-with-events
|
||||
(cond
|
||||
;; w32notify does not distinguish between `changed' and
|
||||
@ -487,7 +487,7 @@ longer than timeout seconds for the events to be delivered."
|
||||
file-notify--test-desc
|
||||
(file-notify-add-watch
|
||||
temporary-file-directory
|
||||
'(change) 'file-notify--test-event-handler)))
|
||||
'(change) #'file-notify--test-event-handler)))
|
||||
(file-notify--test-with-events
|
||||
(cond
|
||||
;; w32notify does not raise `deleted' and `stopped'
|
||||
@ -521,7 +521,7 @@ longer than timeout seconds for the events to be delivered."
|
||||
(setq file-notify--test-desc
|
||||
(file-notify-add-watch
|
||||
file-notify--test-tmpfile
|
||||
'(attribute-change) 'file-notify--test-event-handler)))
|
||||
'(attribute-change) #'file-notify--test-event-handler)))
|
||||
(file-notify--test-with-events
|
||||
(cond
|
||||
;; w32notify does not distinguish between `changed' and
|
||||
@ -743,9 +743,9 @@ longer than timeout seconds for the events to be delivered."
|
||||
|
||||
(unwind-protect
|
||||
(progn
|
||||
(setq file-notify--test-tmpfile
|
||||
(file-name-as-directory (file-notify--test-make-temp-name)))
|
||||
(make-directory file-notify--test-tmpfile)
|
||||
(should
|
||||
(setq file-notify--test-tmpfile
|
||||
(make-temp-file "file-notify-test-parent" t)))
|
||||
(should
|
||||
(setq file-notify--test-desc
|
||||
(file-notify-add-watch
|
||||
@ -765,9 +765,9 @@ longer than timeout seconds for the events to be delivered."
|
||||
|
||||
(unwind-protect
|
||||
(progn
|
||||
(setq file-notify--test-tmpfile
|
||||
(file-name-as-directory (file-notify--test-make-temp-name)))
|
||||
(make-directory file-notify--test-tmpfile)
|
||||
(should
|
||||
(setq file-notify--test-tmpfile
|
||||
(make-temp-file "file-notify-test-parent" t)))
|
||||
(should
|
||||
(setq file-notify--test-desc
|
||||
(file-notify-add-watch
|
||||
@ -795,13 +795,14 @@ longer than timeout seconds for the events to be delivered."
|
||||
;; Under cygwin events arrive in random order. Impossible to define a test.
|
||||
(skip-unless (not (eq system-type 'cygwin)))
|
||||
|
||||
(setq file-notify--test-tmpfile (file-notify--test-make-temp-name))
|
||||
(make-directory file-notify--test-tmpfile)
|
||||
(should
|
||||
(setq file-notify--test-tmpfile
|
||||
(make-temp-file "file-notify-test-parent" t)))
|
||||
(should
|
||||
(setq file-notify--test-desc
|
||||
(file-notify-add-watch
|
||||
file-notify--test-tmpfile
|
||||
'(change) 'file-notify--test-event-handler)))
|
||||
'(change) #'file-notify--test-event-handler)))
|
||||
(unwind-protect
|
||||
(let ((n 1000)
|
||||
source-file-list target-file-list
|
||||
@ -1058,6 +1059,47 @@ the file watch."
|
||||
(file-notify--deftest-remote file-notify-test08-watched-file-in-watched-dir
|
||||
"Check `file-notify-test08-watched-file-in-watched-dir' for remote files.")
|
||||
|
||||
(ert-deftest file-notify-test09-sufficient-ressources ()
|
||||
"Check that file notification does not use too many ressources."
|
||||
:tags '(:expensive-test)
|
||||
(skip-unless (file-notify--test-local-enabled))
|
||||
;; This test is intended for kqueue only.
|
||||
(skip-unless (string-equal (file-notify--test-library) "kqueue"))
|
||||
|
||||
(should
|
||||
(setq file-notify--test-tmpfile
|
||||
(make-temp-file "file-notify-test-parent" t)))
|
||||
(unwind-protect
|
||||
(let ((temporary-file-directory file-notify--test-tmpfile)
|
||||
descs)
|
||||
(should-error
|
||||
(while t
|
||||
;; We watch directories, because we want to reach the upper
|
||||
;; limit. Watching a file might not be sufficient, because
|
||||
;; most of the libraries implement this as watching the
|
||||
;; upper directory.
|
||||
(setq file-notify--test-tmpfile1
|
||||
(make-temp-file "file-notify-test-parent" t)
|
||||
descs
|
||||
(cons
|
||||
(should
|
||||
(file-notify-add-watch
|
||||
file-notify--test-tmpfile1 '(change) #'ignore))
|
||||
descs)))
|
||||
:type 'file-notify-error)
|
||||
;; Remove watches. If we don't do it prior removing
|
||||
;; directories, Emacs crashes in batch mode.
|
||||
(dolist (desc descs)
|
||||
(file-notify-rm-watch desc))
|
||||
;; Remove directories.
|
||||
(delete-directory file-notify--test-tmpfile 'recursive))
|
||||
|
||||
;; Cleanup.
|
||||
(file-notify--test-cleanup)))
|
||||
|
||||
(file-notify--deftest-remote file-notify-test09-sufficient-ressources
|
||||
"Check `file-notify-test09-sufficient-ressources' for remote files.")
|
||||
|
||||
(defun file-notify-test-all (&optional interactive)
|
||||
"Run all tests for \\[file-notify]."
|
||||
(interactive "p")
|
||||
|
Loading…
Reference in New Issue
Block a user