diff options
Diffstat (limited to 'src/kqueue.c')
| -rw-r--r-- | src/kqueue.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/src/kqueue.c b/src/kqueue.c index fa541764169..ca0e3e7e1ca 100644 --- a/src/kqueue.c +++ b/src/kqueue.c | |||
| @@ -35,10 +35,6 @@ static int kqueuefd = -1; | |||
| 35 | /* This is a list, elements are (DESCRIPTOR FILE FLAGS CALLBACK [DIRLIST]). */ | 35 | /* This is a list, elements are (DESCRIPTOR FILE FLAGS CALLBACK [DIRLIST]). */ |
| 36 | static Lisp_Object watch_list; | 36 | static Lisp_Object watch_list; |
| 37 | 37 | ||
| 38 | /* Pending events, being the target of a rename operation. | ||
| 39 | Items are (INODE FILE-NAME LAST-MOD LAST-STATUS-MOD SIZE). */ | ||
| 40 | static Lisp_Object pending_events; | ||
| 41 | |||
| 42 | /* Generate a list from the directory_files_internal output. | 38 | /* Generate a list from the directory_files_internal output. |
| 43 | Items are (INODE FILE-NAME LAST-MOD LAST-STATUS-MOD SIZE). */ | 39 | Items are (INODE FILE-NAME LAST-MOD LAST-STATUS-MOD SIZE). */ |
| 44 | Lisp_Object | 40 | Lisp_Object |
| @@ -115,9 +111,11 @@ static void | |||
| 115 | kqueue_compare_dir_list | 111 | kqueue_compare_dir_list |
| 116 | (Lisp_Object watch_object) | 112 | (Lisp_Object watch_object) |
| 117 | { | 113 | { |
| 118 | Lisp_Object dir, old_directory_files, old_dl, new_directory_files, new_dl, dl; | 114 | Lisp_Object dir, pending_events; |
| 115 | Lisp_Object old_directory_files, old_dl, new_directory_files, new_dl, dl; | ||
| 119 | 116 | ||
| 120 | dir = XCAR (XCDR (watch_object)); | 117 | dir = XCAR (XCDR (watch_object)); |
| 118 | pending_events = Qnil; | ||
| 121 | 119 | ||
| 122 | old_directory_files = Fnth (make_number (4), watch_object); | 120 | old_directory_files = Fnth (make_number (4), watch_object); |
| 123 | old_dl = kqueue_directory_listing (old_directory_files); | 121 | old_dl = kqueue_directory_listing (old_directory_files); |
| @@ -198,6 +196,7 @@ kqueue_compare_dir_list | |||
| 198 | (watch_object, Fcons (Qrename, Qnil), | 196 | (watch_object, Fcons (Qrename, Qnil), |
| 199 | XCAR (XCDR (old_entry)), XCAR (XCDR (new_entry))); | 197 | XCAR (XCDR (old_entry)), XCAR (XCDR (new_entry))); |
| 200 | new_dl = Fdelq (new_entry, new_dl); | 198 | new_dl = Fdelq (new_entry, new_dl); |
| 199 | pending_events = Fdelq (new_entry, pending_events); | ||
| 201 | } | 200 | } |
| 202 | 201 | ||
| 203 | the_end: | 202 | the_end: |
| @@ -208,31 +207,50 @@ kqueue_compare_dir_list | |||
| 208 | /* Parse through the resulting new list. */ | 207 | /* Parse through the resulting new list. */ |
| 209 | dl = new_dl; | 208 | dl = new_dl; |
| 210 | while (1) { | 209 | while (1) { |
| 211 | Lisp_Object new_entry; | 210 | Lisp_Object entry; |
| 212 | if (NILP (dl)) | 211 | if (NILP (dl)) |
| 213 | break; | 212 | break; |
| 214 | 213 | ||
| 215 | /* A new file has appeared. */ | 214 | /* A new file has appeared. */ |
| 216 | new_entry = XCAR (dl); | 215 | entry = XCAR (dl); |
| 217 | kqueue_generate_event | 216 | kqueue_generate_event |
| 218 | (watch_object, Fcons (Qcreate, Qnil), XCAR (XCDR (new_entry)), Qnil); | 217 | (watch_object, Fcons (Qcreate, Qnil), XCAR (XCDR (entry)), Qnil); |
| 219 | 218 | ||
| 220 | /* Check size of that file. */ | 219 | /* Check size of that file. */ |
| 221 | Lisp_Object size = Fnth (make_number (4), new_entry); | 220 | Lisp_Object size = Fnth (make_number (4), entry); |
| 222 | if (FLOATP (size) || (XINT (size) > 0)) | 221 | if (FLOATP (size) || (XINT (size) > 0)) |
| 223 | kqueue_generate_event | 222 | kqueue_generate_event |
| 224 | (watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (new_entry)), Qnil); | 223 | (watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (entry)), Qnil); |
| 225 | 224 | ||
| 226 | dl = XCDR (dl); | 225 | dl = XCDR (dl); |
| 227 | new_dl = Fdelq (new_entry, new_dl); | 226 | new_dl = Fdelq (entry, new_dl); |
| 228 | } | 227 | } |
| 229 | 228 | ||
| 230 | /* At this point, both old_dl and new_dl shall be empty. Let's make | 229 | /* Parse through the resulting pending_events_list. */ |
| 231 | a check for this (might be removed once the code is stable). */ | 230 | dl = pending_events; |
| 231 | while (1) { | ||
| 232 | Lisp_Object entry; | ||
| 233 | if (NILP (dl)) | ||
| 234 | break; | ||
| 235 | |||
| 236 | /* A file is still pending. Assume it was a write. */ | ||
| 237 | entry = XCAR (dl); | ||
| 238 | kqueue_generate_event | ||
| 239 | (watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (entry)), Qnil); | ||
| 240 | |||
| 241 | dl = XCDR (dl); | ||
| 242 | pending_events = Fdelq (entry, pending_events); | ||
| 243 | } | ||
| 244 | |||
| 245 | /* At this point, old_dl, new_dl and pending_events shall be empty. | ||
| 246 | Let's make a check for this (might be removed once the code is | ||
| 247 | stable). */ | ||
| 232 | if (! NILP (old_dl)) | 248 | if (! NILP (old_dl)) |
| 233 | report_file_error ("Old list not empty", old_dl); | 249 | report_file_error ("Old list not empty", old_dl); |
| 234 | if (! NILP (new_dl)) | 250 | if (! NILP (new_dl)) |
| 235 | report_file_error ("New list not empty", new_dl); | 251 | report_file_error ("New list not empty", new_dl); |
| 252 | if (! NILP (pending_events)) | ||
| 253 | report_file_error ("Pending events not empty", new_dl); | ||
| 236 | 254 | ||
| 237 | /* Replace old directory listing with the new one. */ | 255 | /* Replace old directory listing with the new one. */ |
| 238 | XSETCDR (Fnthcdr (make_number (3), watch_object), | 256 | XSETCDR (Fnthcdr (make_number (3), watch_object), |
| @@ -456,7 +474,6 @@ void | |||
| 456 | globals_of_kqueue (void) | 474 | globals_of_kqueue (void) |
| 457 | { | 475 | { |
| 458 | watch_list = Qnil; | 476 | watch_list = Qnil; |
| 459 | pending_events = Qnil; | ||
| 460 | } | 477 | } |
| 461 | 478 | ||
| 462 | void | 479 | void |