[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Using glib's g_file_monitor_file and g_file_monitor_directory
From: |
Paul Eggert |
Subject: |
Re: Using glib's g_file_monitor_file and g_file_monitor_directory |
Date: |
Mon, 03 Jun 2013 23:45:30 -0700 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130510 Thunderbird/17.0.6 |
A quick review of some of the C-level changes:
* The XIL ((EMACS_INT) monitor) trick doesn't work in
general, since the monitor address could look like a
tagged Emacs object and the garbage collector could
go kaflooey on it. Instead, perhaps use make_save_pointer,
as it's designed for this sort of thing.
* Faster and simpler than FUNCTIONP (CDR_SAFE (watch_object))
is CONSP (watch_object). Since the user can't modify
the watch list we can rely on it to be a list of pairs.
* report_file_error reads errno, so it's not suitable
when errno's value is indeterminate.
xsignal... (Qfile_error, ...) is preferable.
Maybe something like the following patch? I couldn't get
this stuff to work on my Fedora 17 host, either without or
with the patch, but it should be necessary to apply something
like the following.
=== modified file 'src/gfilenotify.c'
--- src/gfilenotify.c 2013-06-03 13:03:05 +0000
+++ src/gfilenotify.c 2013-06-04 06:43:23 +0000
@@ -95,21 +95,26 @@ dir_monitor_callback (GFileMonitor* moni
}
/* Determine callback function. */
- watch_object = Fassoc (XIL ((EMACS_INT) monitor), watch_list);
+ for (watch_object = watch_list;
+ CONSP (watch_object);
+ watch_object = XCDR (watch_object))
+ if (XSAVE_POINTER (XCAR (watch_object), 0) == monitor)
+ break;
- if (FUNCTIONP (CDR_SAFE (watch_object)))
+ if (CONSP (watch_object))
{
/* Construct an event. */
struct input_event event;
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 (XCAR (watch_object),
+ Fcons (symbol,
+ Fcons (build_string (name),
+ (oname
+ ? list1 (build_string (oname))
+ : Qnil)))),
+ XCDR (watch_object));
/* Store it into the input event queue. */
kbd_buffer_store_event (&event);
@@ -194,10 +199,10 @@ will be reported only in case of the 'mo
g_signal_connect (monitor, "changed",
(GCallback) dir_monitor_callback, NULL);
else
- report_file_error ("Cannot watch file", Fcons (file, Qnil));
+ xsignal2 (Qfile_error, build_string ("Cannot watch file"), file);
/* Store watch object in watch list. */
- watch_descriptor = XIL ((EMACS_INT) monitor);
+ watch_descriptor = make_save_pointer (monitor);
watch_object = Fcons (watch_descriptor, callback);
watch_list = Fcons (watch_object, watch_list);
@@ -210,20 +215,20 @@ DEFUN ("gfile-rm-watch", Fgfile_rm_watch
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);
+ GFileMonitor *monitor;
+ Lisp_Object watch_object = Fassq (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);
+ monitor = XSAVE_POINTER (XCAR (watch_object), 0);
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);
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Eli Zaretskii, 2013/06/02
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Michael Albinus, 2013/06/03
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Eli Zaretskii, 2013/06/03
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Glenn Morris, 2013/06/03
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Eli Zaretskii, 2013/06/03
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Eli Zaretskii, 2013/06/03
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Glenn Morris, 2013/06/03
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Michael Albinus, 2013/06/03
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory,
Paul Eggert <=
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Eli Zaretskii, 2013/06/04
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Paul Eggert, 2013/06/04
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Stefan Monnier, 2013/06/04
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Paul Eggert, 2013/06/06
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Paul Eggert, 2013/06/04
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Michael Albinus, 2013/06/05
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Jan Djärv, 2013/06/05
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Michael Albinus, 2013/06/06
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Jan Djärv, 2013/06/07
- Re: Using glib's g_file_monitor_file and g_file_monitor_directory, Michael Albinus, 2013/06/07