diff options
author | Michael Albinus <michael.albinus@gmx.de> | 2015-11-19 09:58:08 +0000 |
---|---|---|
committer | Michael Albinus <michael.albinus@gmx.de> | 2015-11-25 15:07:12 +0100 |
commit | c8e266ff5f1862567a9f4b77b2d90b8586b12539 (patch) | |
tree | fd41673a09a4187aa258990f65ef208c3f0d8a82 | |
parent | 5044bdfed7a0bcf091583816ab8a95621138e7fe (diff) |
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.
-rw-r--r-- | src/kqueue.c | 25 | ||||
-rw-r--r-- | test/automated/file-notify-tests.el | 10 |
2 files changed, 23 insertions, 12 deletions
diff --git a/src/kqueue.c b/src/kqueue.c index e2c9dabcb2..fa54176416 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 f0068c547a..b9cd192dd1 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") |