diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2013-06-06 00:04:35 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2013-06-06 00:04:35 -0700 |
commit | 7d300d644cc3c1595d2ac67e37fde1d3d865af24 (patch) | |
tree | e9971162da1ef49fd497486891d78388602d10d9 /src/gfilenotify.c | |
parent | 93df970c5e7219d08c49fe0cb4c2a2b32a1b3d99 (diff) | |
download | emacs-7d300d644cc3c1595d2ac67e37fde1d3d865af24.tar.gz |
A few porting etc. fixes for the new file monitor code.
See the thread containing
<http://lists.gnu.org/archive/html/emacs-devel/2013-06/msg00109.html>.
* gfilenotify.c (dir_monitor_callback, Fgfile_add_watch)
(Fgfile_rm_watch): Don't assume EMACS_INT is the same width as a pointer.
(dir_monitor_callback, Fgfile_rm_watch):
Use assq_no_quit instead of Fassoc, for speed.
(dir_monitor_callback, Fgfile_rm_watch):
eassert that the monitor is a fixnum.
(dir_monitor_callback): No need for CDR_SAFE.
Simplify building of lisp with alternative tails.
(Fgfile_add_watch, Fgfile_rm_watch):
Do not assume glib functions set errno reliably on failure.
(Fgfile_add_watch): Check that the monitor survives the XIL trick,
and signal an error otherwise.
(Fgfile_rm_watch): Prefer CONSP to !NILP.
Use Fdelq instead of Fdelete, for speed.
Diffstat (limited to 'src/gfilenotify.c')
-rw-r--r-- | src/gfilenotify.c | 70 |
1 files changed, 42 insertions, 28 deletions
diff --git a/src/gfilenotify.c b/src/gfilenotify.c index 9b93961f172..c8d12ce8fa0 100644 --- a/src/gfilenotify.c +++ b/src/gfilenotify.c @@ -53,13 +53,13 @@ static Lisp_Object watch_list; g_file_monitor. It shall create a Lisp event, and put it into Emacs input queue. */ static gboolean -dir_monitor_callback (GFileMonitor* monitor, - GFile* file, - GFile* other_file, +dir_monitor_callback (GFileMonitor *monitor, + GFile *file, + GFile *other_file, GFileMonitorEvent event_type, gpointer user_data) { - Lisp_Object symbol, watch_object; + Lisp_Object symbol, monitor_object, watch_object; char *name = g_file_get_parse_name (file); char *oname = other_file ? g_file_get_parse_name (other_file) : NULL; @@ -95,21 +95,23 @@ dir_monitor_callback (GFileMonitor* monitor, } /* Determine callback function. */ - watch_object = Fassoc (XIL ((EMACS_INT) monitor), watch_list); + monitor_object = XIL ((intptr_t) monitor); + eassert (INTEGERP (monitor_object)); + watch_object = assq_no_quit (monitor_object, watch_list); - if (FUNCTIONP (CDR_SAFE (watch_object))) + if (CONSP (watch_object)) { /* Construct an event. */ struct input_event event; + Lisp_Object otail = oname ? list1 (build_string (oname)) : Qnil; EVENT_INIT (event); event.kind = FILE_NOTIFY_EVENT; event.frame_or_window = Qnil; - event.arg = oname - ? list2 (list4 (XIL ((EMACS_INT) monitor), symbol, - build_string (name), build_string (oname)), - CDR_SAFE (watch_object)) - : list2 (list3 (XIL ((EMACS_INT) monitor), symbol, build_string (name)), - CDR_SAFE (watch_object)); + event.arg = list2 (Fcons (monitor_object, + Fcons (symbol, + Fcons (build_string (name), + otail))), + XCDR (watch_object)); /* Store it into the input event queue. */ kbd_buffer_store_event (&event); @@ -165,7 +167,7 @@ will be reported only in case of the 'moved' event. */) { Lisp_Object watch_descriptor, watch_object; GFile *gfile; - GFileMonitor* monitor; + GFileMonitor *monitor; GFileMonitorFlags gflags = G_FILE_MONITOR_NONE; /* Check parameters. */ @@ -190,14 +192,23 @@ will be reported only in case of the 'moved' event. */) /* Enable watch. */ monitor = g_file_monitor (gfile, gflags, NULL, NULL); - if (monitor != NULL) - g_signal_connect (monitor, "changed", - (GCallback) dir_monitor_callback, NULL); - else - report_file_error ("Cannot watch file", Fcons (file, Qnil)); + if (! monitor) + xsignal2 (Qfile_error, build_string ("Cannot watch file"), file); + + /* On all known glib platforms, converting MONITOR directly to a + Lisp_Object value results is a Lisp integer, which is safe. This + assumption is dicey, though, so check it now. */ + watch_descriptor = XIL ((intptr_t) monitor); + if (! INTEGERP (watch_descriptor)) + { + g_object_unref (monitor); + xsignal2 (Qfile_error, build_string ("Unsupported file watcher"), file); + } + + g_signal_connect (monitor, "changed", + (GCallback) dir_monitor_callback, NULL); /* Store watch object in watch list. */ - watch_descriptor = XIL ((EMACS_INT) monitor); watch_object = Fcons (watch_descriptor, callback); watch_list = Fcons (watch_object, watch_list); @@ -210,20 +221,23 @@ DEFUN ("gfile-rm-watch", Fgfile_rm_watch, Sgfile_rm_watch, 1, 1, 0, WATCH-DESCRIPTOR should be an object returned by `gfile-add-watch'. */) (Lisp_Object watch_descriptor) { - Lisp_Object watch_object; - GFileMonitor *monitor = (GFileMonitor *) XLI (watch_descriptor); + intptr_t int_monitor; + GFileMonitor *monitor; + Lisp_Object watch_object = assq_no_quit (watch_descriptor, watch_list); - watch_object = Fassoc (watch_descriptor, watch_list); - if (NILP (watch_object)) - report_file_error ("Not a watch descriptor", - Fcons (watch_descriptor, Qnil)); + if (! CONSP (watch_object)) + xsignal2 (Qfile_error, build_string ("Not a watch descriptor"), + watch_descriptor); + eassert (INTEGERP (watch_descriptor)); + int_monitor = XLI (watch_descriptor); + monitor = (GFileMonitor *) int_monitor; if (!g_file_monitor_cancel (monitor)) - report_file_error ("Could not rm watch", - Fcons (watch_descriptor, Qnil)); + xsignal2 (Qfile_error, build_string ("Could not rm watch"), + watch_descriptor); /* Remove watch descriptor from watch list. */ - watch_list = Fdelete (watch_object, watch_list); + watch_list = Fdelq (watch_object, watch_list); /* Cleanup. */ g_object_unref (monitor); |