From: Michael Albinus Date: Thu, 19 Nov 2015 09:58:08 +0000 (+0000) Subject: Handle more complex rename operation in kqueue X-Git-Tag: emacs-26.0.90~2931^2~4 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=c8e266ff5f1862567a9f4b77b2d90b8586b12539;p=emacs.git Handle more complex rename operation in kqueue * src/kqueue.c (pending_events): New variable. (kqueue_compare_dir_list): Handle more complex rename operation. (globals_of_kqueue): Initialize pending_events. * test/automated/file-notify-tests.el (file-notify-test06-many-events): Adapt expected events in the `rename-file' case. (file-notify-test06-many-events-remote): Declare. --- diff --git a/src/kqueue.c b/src/kqueue.c index e2c9dabcb20..fa541764169 100644 --- a/src/kqueue.c +++ b/src/kqueue.c @@ -35,6 +35,10 @@ static int kqueuefd = -1; /* This is a list, elements are (DESCRIPTOR FILE FLAGS CALLBACK [DIRLIST]). */ static Lisp_Object watch_list; +/* Pending events, being the target of a rename operation. + Items are (INODE FILE-NAME LAST-MOD LAST-STATUS-MOD SIZE). */ +static Lisp_Object pending_events; + /* Generate a list from the directory_files_internal output. Items are (INODE FILE-NAME LAST-MOD LAST-STATUS-MOD SIZE). */ Lisp_Object @@ -136,7 +140,7 @@ kqueue_compare_dir_list /* Search for an entry with the same inode. */ old_entry = XCAR (dl); - new_entry = Fassoc (XCAR (old_entry), new_dl); + new_entry = assq_no_quit (XCAR (old_entry), new_dl); if (! NILP (Fequal (old_entry, new_entry))) { /* Both entries are identical. Nothing to do. */ new_dl = Fdelq (new_entry, new_dl); @@ -177,16 +181,24 @@ kqueue_compare_dir_list new_entry = XCAR (dl1); if (strcmp (SSDATA (XCAR (XCDR (old_entry))), SSDATA (XCAR (XCDR (new_entry)))) == 0) { - kqueue_generate_event - (watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (old_entry)), Qnil); + pending_events = Fcons (new_entry, pending_events); new_dl = Fdelq (new_entry, new_dl); goto the_end; } } - /* The file has been deleted. */ - kqueue_generate_event - (watch_object, Fcons (Qdelete, Qnil), XCAR (XCDR (old_entry)), Qnil); + new_entry = assq_no_quit (XCAR (old_entry), pending_events); + if (NILP (new_entry)) + /* The file has been deleted. */ + kqueue_generate_event + (watch_object, Fcons (Qdelete, Qnil), XCAR (XCDR (old_entry)), Qnil); + else { + /* The file has been renamed. */ + kqueue_generate_event + (watch_object, Fcons (Qrename, Qnil), + XCAR (XCDR (old_entry)), XCAR (XCDR (new_entry))); + new_dl = Fdelq (new_entry, new_dl); + } the_end: dl = XCDR (dl); @@ -444,6 +456,7 @@ void globals_of_kqueue (void) { watch_list = Qnil; + pending_events = Qnil; } void diff --git a/test/automated/file-notify-tests.el b/test/automated/file-notify-tests.el index f0068c547a5..b9cd192dd19 100644 --- a/test/automated/file-notify-tests.el +++ b/test/automated/file-notify-tests.el @@ -661,12 +661,7 @@ Don't wait longer than timeout seconds for the events to be delivered." (write-region "" nil file nil 'no-message)) (dolist (file y-file-list) (write-region "" nil file nil 'no-message))) - (file-notify--test-with-events (cond - ;; XXX Different results? - ((featurep 'kqueue) - (append (make-list n 'changed) - (make-list n 'deleted))) - (t (make-list n 'renamed))) + (file-notify--test-with-events (make-list n 'renamed) (let ((x-file-list x-file-list) (y-file-list y-file-list)) (while (and x-file-list y-file-list) @@ -676,6 +671,9 @@ Don't wait longer than timeout seconds for the events to be delivered." (delete-file file)))) (file-notify--test-cleanup))) +(file-notify--deftest-remote file-notify-test06-many-events + "Check that events are not dropped remote directories.") + (defun file-notify-test-all (&optional interactive) "Run all tests for \\[file-notify]." (interactive "p")