]> code.delx.au - gnu-emacs/commitdiff
Implement gfile-valid-p
authorMichael Albinus <michael.albinus@gmx.de>
Tue, 22 Sep 2015 06:40:08 +0000 (08:40 +0200)
committerMichael Albinus <michael.albinus@gmx.de>
Tue, 22 Sep 2015 06:40:08 +0000 (08:40 +0200)
* lisp/filenotify.el (file-notify-callback): Fix typo.
(gfile-valid-p): Remove defalias.

* src/gfilenotify.c (dir_monitor_callback): Cancel the monitor if
the file or directory to be watched is deleted.
(Fgfile_add_watch): Make watch_object a triple.
(Fgfile_rm_watch): Check, whether watch is cancelled already.
(Fgfile_valid_p): New defun.
(syms_of_gfilenotify): Declare Sgfile_valid_p.

lisp/filenotify.el
src/gfilenotify.c

index b3490fd3ebba299bf22d213d11aeee1f9ba33be8..e2c0af0d1b7e4572e08907534e364e0a47c48ac7 100644 (file)
@@ -161,7 +161,7 @@ EVENT is the cadr of the event in `file-notify-handle-event'
               ((eq action 'attrib) 'attribute-changed)
               ((memq action '(create added)) 'created)
               ((memq action '(modify modified)) 'changed)
-              ((memq action '(delete 'delete-self move-self removed)) 'deleted)
+              ((memq action '(delete delete-self move-self removed)) 'deleted)
               ;; Make the event pending.
               ((memq action '(moved-from renamed-from))
                (setq file-notify--pending-event
@@ -359,9 +359,6 @@ DESCRIPTOR should be an object returned by `file-notify-add-watch'."
                desc))
           (file-notify-error nil))))))
 
-;; Temporary declarations.
-(defalias 'gfile-valid-p 'identity)
-
 (defun file-notify-valid-p (descriptor)
   "Check a watch specified by its DESCRIPTOR.
 DESCRIPTOR should be an object returned by `file-notify-add-watch'."
index 5c6ebe65d870971c67338548dc8fbf9fb7f79f1d..1439666f5f82c7a749c127843a6fc239a4edf94d 100644 (file)
@@ -29,6 +29,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "process.h"
 
 \f
+/* This is a list, elements are triples (DESCRIPTOR FILE CALLBACK)  */
 static Lisp_Object watch_list;
 
 /* This is the callback function for arriving signals from
@@ -93,10 +94,17 @@ dir_monitor_callback (GFileMonitor *monitor,
                                Fcons (symbol,
                                       Fcons (build_string (name),
                                              otail))),
-                        XCDR (watch_object));
+                        XCAR (XCDR (XCDR (watch_object))));
 
       /* Store it into the input event queue.  */
       kbd_buffer_store_event (&event);
+
+      /* Cancel monitor if file or directory is deleted.  */
+      if (((event_type == G_FILE_MONITOR_EVENT_DELETED) ||
+          (event_type == G_FILE_MONITOR_EVENT_MOVED)) &&
+         (strcmp (name, SSDATA (XCAR (XCDR (watch_object)))) == 0) &&
+         (!g_file_monitor_is_cancelled (monitor)))
+       g_file_monitor_cancel (monitor);
     }
 
   /* Cleanup.  */
@@ -198,13 +206,13 @@ will be reported only in case of the `moved' event.  */)
                    (GCallback) dir_monitor_callback, NULL);
 
   /* Store watch object in watch list.  */
-  watch_object = Fcons (watch_descriptor, callback);
+  watch_object = list3 (watch_descriptor, file, callback);
   watch_list = Fcons (watch_object, watch_list);
 
   return watch_descriptor;
 }
 
-DEFUN ("gfile-rm-watch", Fgfile_rm_watch, Sgfile_rm_watch, 1, 1, 0,
+DEFUN ("gfile-rm-watc", Fgfile_rm_watch, Sgfile_rm_watch, 1, 1, 0,
        doc: /* Remove an existing WATCH-DESCRIPTOR.
 
 WATCH-DESCRIPTOR should be an object returned by `gfile-add-watch'.  */)
@@ -218,11 +226,12 @@ WATCH-DESCRIPTOR should be an object returned by `gfile-add-watch'.  */)
 
   eassert (INTEGERP (watch_descriptor));
   GFileMonitor *monitor = XINTPTR (watch_descriptor);
-  if (!g_file_monitor_cancel (monitor))
-    xsignal2 (Qfile_notify_error, build_string ("Could not rm watch"),
-             watch_descriptor);
+  if (!g_file_monitor_is_cancelled (monitor) &&
+      !g_file_monitor_cancel (monitor))
+      xsignal2 (Qfile_notify_error, build_string ("Could not rm watch"),
+               watch_descriptor);
 
-  /* Remove watch descriptor from watch list. */
+  /* Remove watch descriptor from watch list.  */
   watch_list = Fdelq (watch_object, watch_list);
 
   /* Cleanup.  */
@@ -231,6 +240,27 @@ WATCH-DESCRIPTOR should be an object returned by `gfile-add-watch'.  */)
   return Qt;
 }
 
+DEFUN ("gfile-valid-p", Fgfile_valid_p, Sgfile_valid_p, 1, 1, 0,
+       doc: /* "Check a watch specified by its WATCH-DESCRIPTOR.
+
+WATCH-DESCRIPTOR should be an object returned by `gfile-add-watch'.
+
+A watch can become invalid if the file or directory it watches is
+deleted, or if the watcher thread exits abnormally for any other
+reason.  Removing the watch by calling `gfile-rm-watch' also makes it
+invalid.  */)
+     (Lisp_Object watch_descriptor)
+{
+  Lisp_Object watch_object = Fassoc (watch_descriptor, watch_list);
+  if (NILP (watch_object))
+    return Qnil;
+  else
+    {
+      GFileMonitor *monitor = XINTPTR (watch_descriptor);
+      return g_file_monitor_is_cancelled (monitor) ? Qnil : Qt;
+    }
+}
+
 \f
 void
 globals_of_gfilenotify (void)
@@ -246,6 +276,7 @@ syms_of_gfilenotify (void)
 {
   defsubr (&Sgfile_add_watch);
   defsubr (&Sgfile_rm_watch);
+  defsubr (&Sgfile_valid_p);
 
   /* Filter objects.  */
   DEFSYM (Qwatch_mounts, "watch-mounts"); /* G_FILE_MONITOR_WATCH_MOUNTS  */