From 752a4a24e99e8d6387d145c008e5d109fca5b399 Mon Sep 17 00:00:00 2001
From: Yevgen Muntyan <17531749+muntyan@users.noreply.github.com>
Date: Fri, 8 Dec 2006 14:55:46 -0600
Subject: [PATCH] Added FAM back; rewrote a bit of MooFileWatch
---
m4/moo-fam.m4 | 45 +-
m4/moo-flags.m4 | 5 +-
moo.mprj | 18 +-
moo/mooedit/mooedit-private.h | 3 +-
moo/mooedit/mooeditfileops.c | 46 +-
moo/mooedit/mooeditor.c | 6 +-
moo/moofileview/moofile.c | 57 +-
moo/moofileview/moofilesystem.c | 20 +-
moo/moopython/pygtk/mooutils-pygtk.defs | 62 +-
moo/mooutils/moofilewatch.c | 1294 +++++++++++------------
moo/mooutils/moofilewatch.h | 101 +-
11 files changed, 716 insertions(+), 941 deletions(-)
diff --git a/m4/moo-fam.m4 b/m4/moo-fam.m4
index 7bdc03d8..36c402fa 100644
--- a/m4/moo-fam.m4
+++ b/m4/moo-fam.m4
@@ -5,10 +5,11 @@ AC_DEFUN([MOO_AC_CHECK_FAM],[
save_CFLAGS="$CFLAGS"
save_LDFLAGS="$LDFLAGS"
- CFLAGS="$CFLAGS $FAM_CFLAGS"
if test x$FAM_LIBS = x; then
FAM_LIBS=-lfam
fi
+
+ CFLAGS="$CFLAGS $FAM_CFLAGS"
LDFLAGS="$LDFLAGS $FAM_LIBS"
AC_CHECK_HEADERS(fam.h,[
@@ -33,15 +34,18 @@ AC_DEFUN([MOO_AC_CHECK_FAM],[
AC_MSG_RESULT($FAM_LIBS)
fi
- MOO_FAM_LIBS=$FAM_LIBS
+ MOO_FAM_CFLAGS="$FAM_CFLAGS"
+ MOO_FAM_LIBS="$FAM_LIBS"
ifelse([$1], , :, [$1])
else
unset FAM_CFLAGS
unset FAM_LIBS
MOO_FAM_LIBS=
+ MOO_FAM_CFLAGS=
ifelse([$2], , [AC_MSG_ERROR(libfam not found)], [$2])
fi
+ AC_SUBST(MOO_FAM_CFLAGS)
AC_SUBST(MOO_FAM_LIBS)
CFLAGS="$save_CFLAGS"
LDFLAGS="$save_LDFLAGS"
@@ -51,26 +55,25 @@ AC_DEFUN([MOO_AC_CHECK_FAM],[
AC_DEFUN([MOO_AC_FAM],[
AC_REQUIRE([MOO_AC_CHECK_OS])
-# AC_ARG_WITH([fam], AC_HELP_STRING([--with-fam], [whether to use fam or gamin for monitoring files in the editor (default = NO)]), [
-# if test x$with_fam = "xyes"; then
-# MOO_USE_FAM="yes"
-# else
-# MOO_USE_FAM="no"
-# fi
-# ],[
-# MOO_USE_FAM="no"
-# ])
+ AC_ARG_WITH([fam], AC_HELP_STRING([--with-fam], [whether to use fam or gamin for monitoring files in the editor (default = NO)]), [
+ if test x$with_fam = "xyes"; then
+ MOO_USE_FAM="yes"
+ else
+ MOO_USE_FAM="no"
+ fi
+ ],[
+ MOO_USE_FAM="no"
+ ])
-# if test x$MOO_OS_UNIX = xyes -a x$MOO_USE_FAM = xyes; then
-# MOO_AC_CHECK_FAM([moo_has_fam=yes],[moo_has_fam=no])
-# if test x$moo_has_fam = xyes; then
-# MOO_USE_FAM="yes"
-# AC_DEFINE(MOO_USE_FAM, 1, [use libfam for monitoring files])
-# else
-# AC_MSG_ERROR([FAM or gamin not found.])
-# fi
-# fi
+ if test x$MOO_OS_UNIX = xyes -a x$MOO_USE_FAM = xyes; then
+ MOO_AC_CHECK_FAM([moo_has_fam=yes],[moo_has_fam=no])
+ if test x$moo_has_fam = xyes; then
+ MOO_USE_FAM="yes"
+ AC_DEFINE(MOO_USE_FAM, 1, [use libfam for monitoring files])
+ else
+ AC_MSG_ERROR([FAM or gamin not found.])
+ fi
+ fi
- MOO_USE_FAM=no
AM_CONDITIONAL(MOO_USE_FAM, test x$MOO_USE_FAM = "xyes")
])
diff --git a/m4/moo-flags.m4 b/m4/moo-flags.m4
index a8df32cb..93175126 100644
--- a/m4/moo-flags.m4
+++ b/m4/moo-flags.m4
@@ -22,9 +22,10 @@ AC_DEFUN([MOO_AC_FLAGS],[
if test x$MOO_OS_MINGW = xyes; then
MOO_LIBS="$MOO_LIBS $GTHREAD_LIBS"
fi;
-
+
if test x$MOO_USE_FAM = xyes; then
- MOO_LIBS="$MOO_LIBS $FAM_LIBS"
+ MOO_CFLAGS="$MOO_CFLAGS $MOO_FAM_CFLAGS"
+ MOO_LIBS="$MOO_LIBS $MOO_FAM_LIBS"
fi
MOO_CFLAGS="$MOO_CFLAGS -DMOO_DATA_DIR=\\\"${MOO_DATA_DIR}\\\" -DMOO_LIB_DIR=\\\"${MOO_LIB_DIR}\\\""
diff --git a/moo.mprj b/moo.mprj
index 9fe9e804..d86b9c0e 100644
--- a/moo.mprj
+++ b/moo.mprj
@@ -11,6 +11,15 @@
+
+ /home/muntyan/projects/gtk/build/moo
+
+ --enable-debug --enable-all-gcc-warnings --prefix=$PREFIX --with-fam
+
+ -g
+
+
+
build/mingw
@@ -23,15 +32,6 @@
-
- /home/muntyan/projects/gtk/build/moo
-
- --enable-debug --enable-all-gcc-warnings --prefix=$PREFIX
-
- -g
-
-
-
--g-fatal-warnings --new-app
diff --git a/moo/mooedit/mooedit-private.h b/moo/mooedit/mooedit-private.h
index 73d090d4..4f178e91 100644
--- a/moo/mooedit/mooedit-private.h
+++ b/moo/mooedit/mooedit-private.h
@@ -132,8 +132,7 @@ struct _MooEditPrivate {
MooEditStatus status;
MooEditOnExternalChanges file_watch_policy;
- int file_monitor_id;
- gulong file_watch_event_handler_id;
+ guint file_monitor_id;
gulong focus_in_handler_id;
gboolean modified_on_disk;
gboolean deleted_from_disk;
diff --git a/moo/mooedit/mooeditfileops.c b/moo/mooedit/mooeditfileops.c
index d4e24445..d8dd2b23 100644
--- a/moo/mooedit/mooeditfileops.c
+++ b/moo/mooedit/mooeditfileops.c
@@ -911,31 +911,30 @@ static void unblock_buffer_signals (MooEdit *edit)
static void
-file_watch_event (G_GNUC_UNUSED MooFileWatch *watch,
- MooFileWatchEvent *event,
- MooEdit *edit)
+file_watch_callback (G_GNUC_UNUSED MooFileWatch *watch,
+ MooFileEvent *event,
+ gpointer data)
{
- if (event->monitor_id != edit->priv->file_monitor_id)
- return;
+ MooEdit *edit = MOO_EDIT (data);
+ g_return_if_fail (event->monitor_id == edit->priv->file_monitor_id);
g_return_if_fail (edit->priv->filename != NULL);
g_return_if_fail (!(edit->priv->status & MOO_EDIT_CHANGED_ON_DISK));
switch (event->code)
{
- case MOO_FILE_WATCH_EVENT_CHANGED:
+ case MOO_FILE_EVENT_CHANGED:
edit->priv->modified_on_disk = TRUE;
break;
- case MOO_FILE_WATCH_EVENT_DELETED:
+ case MOO_FILE_EVENT_DELETED:
edit->priv->deleted_from_disk = TRUE;
edit->priv->file_monitor_id = 0;
break;
- case MOO_FILE_WATCH_EVENT_CREATED:
- case MOO_FILE_WATCH_EVENT_MOVED:
- case MOO_FILE_WATCH_EVENT_ERROR:
- g_return_if_reached ();
+ case MOO_FILE_EVENT_ERROR:
+ /* XXX and what to do now? */
+ break;
}
check_file_status (edit, TRUE);
@@ -949,7 +948,7 @@ _moo_edit_start_file_watch (MooEdit *edit)
GError *error = NULL;
watch = _moo_editor_get_file_watch (edit->priv->editor);
- g_return_if_fail (MOO_IS_FILE_WATCH (watch));
+ g_return_if_fail (watch != NULL);
if (edit->priv->file_monitor_id)
moo_file_watch_cancel_monitor (watch, edit->priv->file_monitor_id);
@@ -958,9 +957,10 @@ _moo_edit_start_file_watch (MooEdit *edit)
g_return_if_fail ((edit->priv->status & MOO_EDIT_CHANGED_ON_DISK) == 0);
g_return_if_fail (edit->priv->filename != NULL);
- edit->priv->file_monitor_id = moo_file_watch_monitor_file (watch,
- edit->priv->filename,
- edit, &error);
+ edit->priv->file_monitor_id =
+ moo_file_watch_create_monitor (watch, edit->priv->filename,
+ file_watch_callback,
+ edit, NULL, &error);
if (!edit->priv->file_monitor_id)
{
@@ -976,12 +976,6 @@ _moo_edit_start_file_watch (MooEdit *edit)
return;
}
- /* XXX watch errors too */
- if (!edit->priv->file_watch_event_handler_id)
- edit->priv->file_watch_event_handler_id =
- g_signal_connect (watch, "event",
- G_CALLBACK (file_watch_event), edit);
-
if (!edit->priv->focus_in_handler_id)
edit->priv->focus_in_handler_id =
g_signal_connect (edit, "focus-in-event",
@@ -991,23 +985,17 @@ _moo_edit_start_file_watch (MooEdit *edit)
void
-_moo_edit_stop_file_watch (MooEdit *edit)
+_moo_edit_stop_file_watch (MooEdit *edit)
{
MooFileWatch *watch;
watch = _moo_editor_get_file_watch (edit->priv->editor);
- g_return_if_fail (MOO_IS_FILE_WATCH (watch));
+ g_return_if_fail (watch != NULL);
if (edit->priv->file_monitor_id)
moo_file_watch_cancel_monitor (watch, edit->priv->file_monitor_id);
edit->priv->file_monitor_id = 0;
- if (edit->priv->file_watch_event_handler_id)
- {
- g_signal_handler_disconnect (watch, edit->priv->file_watch_event_handler_id);
- edit->priv->file_watch_event_handler_id = 0;
- }
-
if (edit->priv->focus_in_handler_id)
{
g_signal_handler_disconnect (edit, edit->priv->focus_in_handler_id);
diff --git a/moo/mooedit/mooeditor.c b/moo/mooedit/mooeditor.c
index e69f4617..969b7762 100644
--- a/moo/mooedit/mooeditor.c
+++ b/moo/mooedit/mooeditor.c
@@ -448,6 +448,7 @@ moo_editor_finalize (GObject *object)
if (editor->priv->file_watch)
{
GError *error = NULL;
+
if (!moo_file_watch_close (editor->priv->file_watch, &error))
{
g_warning ("%s: error in moo_file_watch_close", G_STRLOC);
@@ -457,7 +458,8 @@ moo_editor_finalize (GObject *object)
g_error_free (error);
}
}
- g_object_unref (editor->priv->file_watch);
+
+ moo_file_watch_unref (editor->priv->file_watch);
}
if (editor->priv->windows)
@@ -545,7 +547,7 @@ _moo_editor_post_message (MooEditor *editor,
gpointer
-_moo_editor_get_file_watch (MooEditor *editor)
+_moo_editor_get_file_watch (MooEditor *editor)
{
g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
diff --git a/moo/moofileview/moofile.c b/moo/moofileview/moofile.c
index a8331114..71d59ecf 100644
--- a/moo/moofileview/moofile.c
+++ b/moo/moofileview/moofile.c
@@ -112,7 +112,7 @@ struct _MooFolderPrivate {
Debug debug;
GTimer *timer;
MooFileWatch *fam;
- int fam_request;
+ guint fam_request;
guint reload_idle;
};
@@ -819,44 +819,31 @@ static void file_created (MooFolder *folder,
const char *name);
static void
-fam_event (MooFolder *folder,
- MooFileWatchEvent *event)
+fam_callback (MooFileWatch *watch,
+ MooFileEvent *event,
+ gpointer data)
{
- if (event->data != folder)
- return;
+ MooFolder *folder = MOO_FOLDER (data);
+ g_return_if_fail (watch == folder->priv->fam);
g_return_if_fail (event->monitor_id == folder->priv->fam_request);
switch (event->code)
{
- case MOO_FILE_WATCH_EVENT_CHANGED:
+ case MOO_FILE_EVENT_CHANGED:
file_changed (folder, event->filename);
break;
- case MOO_FILE_WATCH_EVENT_DELETED:
+ case MOO_FILE_EVENT_DELETED:
file_deleted (folder, event->filename);
break;
- case MOO_FILE_WATCH_EVENT_CREATED:
- file_created (folder, event->filename);
- break;
- case MOO_FILE_WATCH_EVENT_ERROR:
- /* XXX */
- file_deleted (folder, folder->priv->path);
- break;
- case MOO_FILE_WATCH_EVENT_MOVED:
+ case MOO_FILE_EVENT_ERROR:
+ stop_monitor (folder);
+ file_changed (folder, folder->priv->path);
break;
}
}
-static void
-fam_error (MooFolder *folder,
- GError *error)
-{
- g_print ("fam error: %s\n", error->message);
- stop_monitor (folder);
-}
-
-
static void
start_monitor (MooFolder *folder)
{
@@ -868,22 +855,18 @@ start_monitor (MooFolder *folder)
g_return_if_fail (folder->priv->fam != NULL);
folder->priv->fam_request =
- moo_file_watch_monitor_directory (folder->priv->fam,
- folder->priv->path,
- folder, &error);
+ moo_file_watch_create_monitor (folder->priv->fam,
+ folder->priv->path,
+ fam_callback, folder,
+ NULL, &error);
if (!folder->priv->fam_request)
{
- g_warning ("%s: moo_fam_monitor_directory failed for path '%s'", G_STRLOC, folder->priv->path);
+ g_warning ("%s: moo_file_watch_create_monitor failed for path '%s'", G_STRLOC, folder->priv->path);
g_warning ("%s: %s", G_STRLOC, error->message);
g_error_free (error);
return;
}
-
- g_signal_connect_swapped (folder->priv->fam, "event",
- G_CALLBACK (fam_event), folder);
- g_signal_connect_swapped (folder->priv->fam, "error",
- G_CALLBACK (fam_error), folder);
}
@@ -892,16 +875,8 @@ stop_monitor (MooFolder *folder)
{
if (folder->priv->fam_request)
{
- g_signal_handlers_disconnect_by_func (folder->priv->fam,
- (gpointer)fam_event,
- folder);
- g_signal_handlers_disconnect_by_func (folder->priv->fam,
- (gpointer)fam_error,
- folder);
-
moo_file_watch_cancel_monitor (folder->priv->fam,
folder->priv->fam_request);
-
folder->priv->fam = NULL;
folder->priv->fam_request = 0;
}
diff --git a/moo/moofileview/moofilesystem.c b/moo/moofileview/moofilesystem.c
index f257893e..2c6d82c6 100644
--- a/moo/moofileview/moofilesystem.c
+++ b/moo/moofileview/moofilesystem.c
@@ -158,7 +158,7 @@ moo_file_system_finalize (GObject *object)
if (fs->priv->fam)
{
moo_file_watch_close (fs->priv->fam, NULL);
- g_object_unref (fs->priv->fam);
+ moo_file_watch_unref (fs->priv->fam);
}
g_free (fs->priv);
@@ -302,19 +302,6 @@ _moo_file_system_get_absolute_path (MooFileSystem *fs,
}
-static void
-fam_error (MooFileWatch *fam,
- GError *error,
- MooFileSystem *fs)
-{
- g_return_if_fail (fs->priv->fam == fam);
- g_warning ("%s: fam error", G_STRLOC);
- g_warning ("%s: %s", G_STRLOC, error->message);
- g_object_unref (fs->priv->fam);
- fs->priv->fam = NULL;
-}
-
-
MooFileWatch *
_moo_file_system_get_file_watch (MooFileSystem *fs)
{
@@ -330,11 +317,6 @@ _moo_file_system_get_file_watch (MooFileSystem *fs)
g_warning ("%s: %s", G_STRLOC, error->message);
g_error_free (error);
}
- else
- {
- g_signal_connect (fs->priv->fam, "error",
- G_CALLBACK (fam_error), fs);
- }
}
return fs->priv->fam;
diff --git a/moo/moopython/pygtk/mooutils-pygtk.defs b/moo/moopython/pygtk/mooutils-pygtk.defs
index c574fdd5..2af8d1c0 100644
--- a/moo/moopython/pygtk/mooutils-pygtk.defs
+++ b/moo/moopython/pygtk/mooutils-pygtk.defs
@@ -22,12 +22,10 @@
(gtype-id "MOO_TYPE_ENTRY")
)
-(define-object FileWatch
+(define-boxed FileWatch
(in-module "Moo")
- (parent "GObject")
(c-name "MooFileWatch")
(gtype-id "MOO_TYPE_FILE_WATCH")
- (final "true")
)
(define-object FilterMgr
@@ -226,15 +224,15 @@
(release-func "moo_closure_unref")
)
-(define-pointer FileWatchEvent
+(define-boxed FileEvent
(in-module "Moo")
- (c-name "MooFileWatchEvent")
- (gtype-id "MOO_TYPE_FILE_WATCH_EVENT")
+ (c-name "MooFileEvent")
+ (gtype-id "MOO_TYPE_FILE_EVENT")
(fields
- '("MooFileWatchEventCode" "code")
+ '("MooFileEventCode" "code")
'("int" "monitor_id")
'("char*" "filename")
- '("gpointer" "data")
+ '("GError*" "error")
)
)
@@ -256,16 +254,10 @@
(gtype-id "MOO_TYPE_FILE_DIALOG_TYPE")
)
-(define-enum FileWatchMethod
+(define-enum FileEventCode
(in-module "Moo")
- (c-name "MooFileWatchMethod")
- (gtype-id "MOO_TYPE_FILE_WATCH_METHOD")
-)
-
-(define-enum FileWatchEventCode
- (in-module "Moo")
- (c-name "MooFileWatchEventCode")
- (gtype-id "MOO_TYPE_FILE_WATCH_EVENT_CODE")
+ (c-name "MooFileEventCode")
+ (gtype-id "MOO_TYPE_FILE_EVENT_CODE")
)
(define-enum PanePosition
@@ -560,11 +552,6 @@
;; From ../mooutils/moofilewatch.h
-;; (define-function moo_file_watch_error_quark
-;; (c-name "moo_file_watch_error_quark")
-;; (return-type "GQuark")
-;; )
-
(define-function moo_file_watch_new
(c-name "moo_file_watch_new")
(is-constructor-of "MooFileWatch")
@@ -583,24 +570,13 @@
)
)
-(define-method monitor_directory
+(define-method create_monitor
(of-object "MooFileWatch")
- (c-name "moo_file_watch_monitor_directory")
- (return-type "int")
- (parameters
- '("const-char*" "filename")
- '("gpointer" "data")
- '("GDestroyNotify" "data_notify")
- '("GError**" "error")
- )
-)
-
-(define-method monitor_file
- (of-object "MooFileWatch")
- (c-name "moo_file_watch_monitor_file")
- (return-type "int")
+ (c-name "moo_file_watch_create_monitor")
+ (return-type "guint")
(parameters
'("const-char*" "filename")
+ '("MooFileWatchCallback" "callback")
'("gpointer" "data")
'("GDestroyNotify" "data_notify")
'("GError**" "error")
@@ -612,7 +588,7 @@
(c-name "moo_file_watch_suspend_monitor")
(return-type "none")
(parameters
- '("int" "monitor_id")
+ '("guint" "monitor_id")
)
)
@@ -621,7 +597,7 @@
(c-name "moo_file_watch_resume_monitor")
(return-type "none")
(parameters
- '("int" "monitor_id")
+ '("guint" "monitor_id")
)
)
@@ -630,16 +606,10 @@
(c-name "moo_file_watch_cancel_monitor")
(return-type "none")
(parameters
- '("int" "monitor_id")
+ '("guint" "monitor_id")
)
)
-(define-method get_method
- (of-object "MooFileWatch")
- (c-name "moo_file_watch_get_method")
- (return-type "MooFileWatchMethod")
-)
-
;; From ../mooutils/moofiltermgr.h
diff --git a/moo/mooutils/moofilewatch.c b/moo/mooutils/moofilewatch.c
index 0d6bf561..a5bab7a7 100644
--- a/moo/mooutils/moofilewatch.c
+++ b/moo/mooutils/moofilewatch.c
@@ -17,6 +17,8 @@
#ifdef MOO_USE_FAM
#include
+#else
+#define WANT_STAT_MONITOR
#endif
#ifdef __WIN32__
@@ -42,7 +44,7 @@
#include "mooutils/moocompat.h"
-#if defined(__WIN32__) && 0
+#if 1 || defined(__WIN32__) && 0
#define DEBUG_PRINT g_message
#else
static void DEBUG_PRINT (G_GNUC_UNUSED const char *format, ...)
@@ -50,229 +52,157 @@ static void DEBUG_PRINT (G_GNUC_UNUSED const char *format, ...)
}
#endif
-static const char *event_code_strings[] = {
- NULL,
- "CHANGED",
- "DELETED",
- "CREATED",
- "MOVED",
- "ERROR"
-};
-
-typedef struct _Monitor Monitor;
-
-typedef enum {
- MONITOR_DIR,
- MONITOR_FILE
-} MonitorType;
-
-struct _Monitor {
- MooFileWatch *parent;
- MonitorType type;
- char *filename;
- gpointer user_data;
- int request;
- guint suspended : 1;
- struct stat statbuf;
-};
-
typedef struct {
- gboolean (*start) (MooFileWatch *watch,
- GError **error);
- gboolean (*shutdown)(MooFileWatch *watch,
- GError **error);
+ guint id;
+ MooFileWatch *watch;
+ char *filename;
- Monitor *(*create) (MooFileWatch *watch,
- MonitorType type,
- const char *filename,
- gpointer data,
- int *request,
- GError **error);
- void (*suspend) (Monitor *monitor);
- void (*resume) (Monitor *monitor);
- void (*delete) (MooFileWatch *watch,
- Monitor *monitor);
-} WatchFuncs;
+ MooFileWatchCallback callback;
+ GDestroyNotify notify;
+ gpointer data;
+ struct stat statbuf;
-struct _MooFileWatchPrivate {
+ guint isdir : 1;
+ guint suspended : 1;
+ guint alive : 1;
+} Monitor;
+
+struct WatchFuncs {
+ gboolean (*start) (MooFileWatch *watch,
+ GError **error);
+ gboolean (*shutdown) (MooFileWatch *watch,
+ GError **error);
+
+ gboolean (*start_monitor) (MooFileWatch *watch,
+ Monitor *monitor,
+ GError **error);
+ void (*stop_monitor) (MooFileWatch *watch,
+ Monitor *monitor);
+ gboolean (*suspend_monitor) (MooFileWatch *watch,
+ Monitor *monitor);
+ gboolean (*resume_monitor) (MooFileWatch *watch,
+ Monitor *monitor);
+};
+
+struct _MooFileWatch {
+ guint ref_count;
+ guint id;
guint stat_timeout;
#ifdef MOO_USE_FAM
FAMConnection fam_connection;
guint fam_connection_watch;
#endif
-#ifdef __WIN32__
- guint id;
-#endif
- WatchFuncs funcs;
- MooFileWatchMethod method;
GSList *monitors;
GHashTable *requests; /* int -> Monitor* */
guint alive : 1;
};
-/* stat and win32 assign id themselves */
-static int last_monitor_id = 0;
-
#ifdef MOO_USE_FAM
-static gboolean watch_fam_start (MooFileWatch *watch,
- GError **error);
-static gboolean watch_fam_shutdown (MooFileWatch *watch,
- GError **error);
-static Monitor *monitor_fam_create (MooFileWatch *watch,
- MonitorType type,
- const char *filename,
- gpointer data,
- int *request,
- GError **error);
-static void monitor_fam_suspend (Monitor *monitor);
-static void monitor_fam_resume (Monitor *monitor);
-static void monitor_fam_delete (MooFileWatch *watch,
- Monitor *monitor);
+static gboolean watch_fam_start (MooFileWatch *watch,
+ GError **error);
+static gboolean watch_fam_shutdown (MooFileWatch *watch,
+ GError **error);
+static gboolean watch_fam_start_monitor (MooFileWatch *watch,
+ Monitor *monitor,
+ GError **error);
+static gboolean watch_fam_suspend_monitor (MooFileWatch *watch,
+ Monitor *monitor);
+static gboolean watch_fam_resume_monitor (MooFileWatch *watch,
+ Monitor *monitor);
+static void watch_fam_stop_monitor (MooFileWatch *watch,
+ Monitor *monitor);
#endif /* MOO_USE_FAM */
-static gboolean watch_stat_start (MooFileWatch *watch,
- GError **error);
-static gboolean watch_stat_shutdown (MooFileWatch *watch,
- GError **error);
-static Monitor *monitor_stat_create (MooFileWatch *watch,
- MonitorType type,
- const char *filename,
- gpointer data,
- int *request,
- GError **error);
-static void monitor_stat_suspend (Monitor *monitor);
-static void monitor_stat_resume (Monitor *monitor);
-static void monitor_stat_delete (MooFileWatch *watch,
- Monitor *monitor);
-
-#ifdef __WIN32__
-static gboolean watch_win32_start (MooFileWatch *watch,
- GError **error);
-static gboolean watch_win32_shutdown (MooFileWatch *watch,
- GError **error);
-static Monitor *monitor_win32_create (MooFileWatch *watch,
- MonitorType type,
- const char *filename,
- gpointer data,
- int *request,
- GError **error);
-static void monitor_win32_suspend (Monitor *monitor);
-static void monitor_win32_resume (Monitor *monitor);
-static void monitor_win32_delete (MooFileWatch *watch,
- Monitor *monitor);
-#endif /* __WIN32__ */
-
-
-/* MOO_TYPE_FILE_WATCH */
-G_DEFINE_TYPE (MooFileWatch, moo_file_watch, G_TYPE_OBJECT)
-
-enum {
- PROP_0,
- PROP_METHOD
-};
-
-enum {
- EVENT,
- ERROR_SIGNAL,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-static void moo_file_watch_finalize (GObject *object);
-
-static void
-moo_file_watch_class_init (MooFileWatchClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->finalize = moo_file_watch_finalize;
-
- signals[EVENT] =
- g_signal_new ("event",
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (MooFileWatchClass, event),
- NULL, NULL,
- _moo_marshal_VOID__POINTER,
- G_TYPE_NONE, 1,
- MOO_TYPE_FILE_WATCH_EVENT);
-
- signals[ERROR_SIGNAL] =
- g_signal_new ("error",
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (MooFileWatchClass, error),
- NULL, NULL,
- _moo_marshal_VOID__POINTER,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER);
-}
-
-
-static void
-moo_file_watch_init (MooFileWatch *watch)
-{
- watch->priv = g_new0 (MooFileWatchPrivate, 1);
- watch->priv->requests = g_hash_table_new (g_direct_hash, g_direct_equal);
-
-#if defined (__WIN32__)
- watch->priv->method = MOO_FILE_WATCH_WIN32;
-#elif defined (MOO_USE_FAM)
- watch->priv->method = MOO_FILE_WATCH_FAM;
-#else
- watch->priv->method = MOO_FILE_WATCH_STAT;
+#ifdef WANT_STAT_MONITOR
+static gboolean watch_stat_start (MooFileWatch *watch,
+ GError **error);
+static gboolean watch_stat_shutdown (MooFileWatch *watch,
+ GError **error);
+static gboolean watch_stat_start_monitor (MooFileWatch *watch,
+ Monitor *monitor,
+ GError **error);
#endif
-#if defined (__WIN32__)
- g_assert (watch->priv->method == MOO_FILE_WATCH_WIN32);
- watch->priv->funcs.start = watch_win32_start;
- watch->priv->funcs.shutdown = watch_win32_shutdown;
- watch->priv->funcs.create = monitor_win32_create;
- watch->priv->funcs.suspend = monitor_win32_suspend;
- watch->priv->funcs.resume = monitor_win32_resume;
- watch->priv->funcs.delete = monitor_win32_delete;
-#else /* !__WIN32__ */
- if (watch->priv->method == MOO_FILE_WATCH_STAT)
- {
- watch->priv->funcs.start = watch_stat_start;
- watch->priv->funcs.shutdown = watch_stat_shutdown;
- watch->priv->funcs.create = monitor_stat_create;
- watch->priv->funcs.suspend = monitor_stat_suspend;
- watch->priv->funcs.resume = monitor_stat_resume;
- watch->priv->funcs.delete = monitor_stat_delete;
- }
-#ifdef MOO_USE_FAM
- else
- {
- watch->priv->funcs.start = watch_fam_start;
- watch->priv->funcs.shutdown = watch_fam_shutdown;
- watch->priv->funcs.create = monitor_fam_create;
- watch->priv->funcs.suspend = monitor_fam_suspend;
- watch->priv->funcs.resume = monitor_fam_resume;
- watch->priv->funcs.delete = monitor_fam_delete;
- }
-#else /* !MOO_USE_FAM */
- else
- {
- g_assert_not_reached ();
- }
-#endif /* !MOO_USE_FAM */
-#endif /* !__WIN32__ */
+#ifdef __WIN32__
+static gboolean watch_win32_start (MooFileWatch *watch,
+ GError **error);
+static gboolean watch_win32_shutdown (MooFileWatch *watch,
+ GError **error);
+static gboolean watch_win32_start_monitor (MooFileWatch *watch,
+ Monitor *monitor,
+ GError **error);
+static gboolean watch_win32_suspend_monitor (MooFileWatch *watch,
+ Monitor *monitor);
+static gboolean watch_win32_resume_monitor (MooFileWatch *watch,
+ Monitor *monitor);
+static void watch_win32_stop_monitor (MooFileWatch *watch,
+ Monitor *monitor);
+#endif /* __WIN32__ */
+
+static Monitor *monitor_new (MooFileWatch *watch,
+ const char *filename,
+ MooFileWatchCallback callback,
+ gpointer data,
+ GDestroyNotify notify);
+static void monitor_free (Monitor *monitor);
+
+
+static guint last_watch_id = 0;
+#if !defined(MOO_USE_FAM) || defined(WANT_STAT_MONITOR)
+static guint last_monitor_id = 0;
+#endif
+
+static struct WatchFuncs watch_funcs = {
+#if defined(MOO_USE_FAM)
+ watch_fam_start,
+ watch_fam_shutdown,
+ watch_fam_start_monitor,
+ watch_fam_stop_monitor,
+ watch_fam_suspend_monitor,
+ watch_fam_resume_monitor
+#elif defined(__WIN32__)
+ watch_win32_start,
+ watch_win32_shutdown,
+ watch_win32_start_monitor,
+ watch_win32_stop_monitor,
+ watch_win32_suspend_monitor,
+ watch_win32_resume_monitor
+#else
+ watch_stat_start,
+ watch_stat_shutdown,
+ watch_stat_start_monitor,
+ NULL,
+ NULL,
+ NULL
+#endif
+};
+
+
+MooFileWatch *
+moo_file_watch_ref (MooFileWatch *watch)
+{
+ g_return_val_if_fail (watch != NULL, watch);
+ watch->ref_count++;
+ return watch;
}
-static void
-moo_file_watch_finalize (GObject *object)
+void
+moo_file_watch_unref (MooFileWatch *watch)
{
GError *error = NULL;
- MooFileWatch *watch = MOO_FILE_WATCH (object);
- if (watch->priv->alive)
+ g_return_if_fail (watch != NULL);
+
+ if (--watch->ref_count)
+ return;
+
+ if (watch->alive)
{
g_warning ("%s: finalizing open watch", G_STRLOC);
+
if (!moo_file_watch_close (watch, &error))
{
g_warning ("%s: error in moo_file_watch_close()", G_STRLOC);
@@ -281,12 +211,48 @@ moo_file_watch_finalize (GObject *object)
}
}
- g_hash_table_destroy (watch->priv->requests);
+ g_hash_table_destroy (watch->requests);
+ g_free (watch);
+}
- g_free (watch->priv);
- watch->priv = NULL;
- G_OBJECT_CLASS(moo_file_watch_parent_class)->finalize (object);
+MooFileWatch *
+moo_file_watch_new (GError **error)
+{
+ MooFileWatch *watch;
+
+ watch = g_new0 (MooFileWatch, 1);
+
+ watch->requests = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ if (!++last_watch_id)
+ ++last_watch_id;
+
+ watch->id = last_watch_id;
+ watch->ref_count = 1;
+
+ if (!watch_funcs.start (watch, error))
+ {
+ moo_file_watch_unref (watch);
+ return NULL;
+ }
+
+ watch->alive = TRUE;
+ return watch;
+}
+
+
+GType
+moo_file_watch_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type)
+ type = g_boxed_type_register_static ("MooFileWatch",
+ (GBoxedCopyFunc) moo_file_watch_ref,
+ (GBoxedFreeFunc) moo_file_watch_unref);
+
+ return type;
}
@@ -300,201 +266,81 @@ moo_file_watch_error_quark (void)
}
-MooFileWatchMethod
-moo_file_watch_get_method (MooFileWatch *watch)
+static MooFileEvent *
+moo_file_event_new (const char *filename,
+ guint monitor_id,
+ MooFileEventCode code)
{
- g_return_val_if_fail (MOO_IS_FILE_WATCH (watch), -1);
- return watch->priv->method;
+ MooFileEvent *event;
+
+ event = g_new0 (MooFileEvent, 1);
+ event->filename = g_strdup (filename);
+ event->monitor_id = monitor_id;
+ event->code = code;
+ event->error = NULL;
+
+ return event;
}
-
-GType
-moo_file_watch_method_get_type (void)
+static MooFileEvent *
+moo_file_event_copy (MooFileEvent *event)
{
- static GType type = 0;
+ MooFileEvent *copy;
- if (!type)
- {
- static const GEnumValue values[] = {
- {MOO_FILE_WATCH_STAT, (char*) "MOO_FILE_WATCH_STAT", (char*) "stat"},
- {MOO_FILE_WATCH_FAM, (char*) "MOO_FILE_WATCH_FAM", (char*) "fam"},
- {MOO_FILE_WATCH_WIN32, (char*) "MOO_FILE_WATCH_WIN32", (char*) "win32"},
- { 0, NULL, NULL }
- };
+ copy = moo_file_event_new (event->filename,
+ event->monitor_id,
+ event->code);
- type = g_enum_register_static ("MooFileWatchMethod", values);
- }
+ if (event->error)
+ copy->error = g_error_copy (event->error);
- return type;
+ return copy;
}
-
-GType
-moo_file_watch_event_get_type (void)
-{
- static GType type = 0;
-
- if (!type)
- type = g_pointer_type_register_static ("MooFileWatchEvent");
-
- return type;
-}
-
-
-GType
-moo_file_watch_event_code_get_type (void)
-{
- static GType type = 0;
-
- if (!type)
- {
- static const GEnumValue values[] = {
- { MOO_FILE_WATCH_EVENT_CHANGED, (char*) "MOO_FILE_WATCH_EVENT_CHANGED", (char*) "changed"},
- { MOO_FILE_WATCH_EVENT_DELETED, (char*) "MOO_FILE_WATCH_EVENT_DELETED", (char*) "deleted"},
- { MOO_FILE_WATCH_EVENT_CREATED, (char*) "MOO_FILE_WATCH_EVENT_CREATED", (char*) "created"},
- { MOO_FILE_WATCH_EVENT_MOVED, (char*) "MOO_FILE_WATCH_EVENT_MOVED", (char*) "moved"},
- { MOO_FILE_WATCH_EVENT_ERROR, (char*) "MOO_FILE_WATCH_EVENT_ERROR", (char*) "error"},
- { 0, NULL, NULL }
- };
-
- type = g_enum_register_static ("MooFileWatchEventCode", values);
- }
-
- return type;
-}
-
-
-static int
-moo_file_watch_create_monitor (MooFileWatch *watch,
- MonitorType type,
- const char *filename,
- gpointer data,
- GError **error)
-{
- Monitor *monitor;
- int request;
-
- g_return_val_if_fail (MOO_IS_FILE_WATCH (watch), FALSE);
- g_return_val_if_fail (filename != NULL, FALSE);
-
- if (!watch->priv->alive)
- {
- g_set_error (error, MOO_FILE_WATCH_ERROR,
- MOO_FILE_WATCH_ERROR_CLOSED,
- "MooFileWatch is closed");
- return FALSE;
- }
-
- monitor = watch->priv->funcs.create (watch, type, filename, data, &request, error);
-
- if (!monitor)
- return 0;
-
- watch->priv->monitors = g_slist_prepend (watch->priv->monitors, monitor);
- g_hash_table_insert (watch->priv->requests, GINT_TO_POINTER (request), monitor);
-
- return request;
-}
-
-
-int
-moo_file_watch_monitor_directory (MooFileWatch *watch,
- const char *filename,
- gpointer data,
- GError **error)
-{
- return moo_file_watch_create_monitor (watch, MONITOR_DIR, filename, data, error);
-}
-
-
-int
-moo_file_watch_monitor_file (MooFileWatch *watch,
- const char *filename,
- gpointer data,
- GError **error)
-{
- return moo_file_watch_create_monitor (watch, MONITOR_FILE, filename, data, error);
-}
-
-
-void
-moo_file_watch_suspend_monitor (MooFileWatch *watch,
- int monitor_id)
-{
- Monitor *monitor;
-
- g_return_if_fail (MOO_IS_FILE_WATCH (watch));
-
- monitor = g_hash_table_lookup (watch->priv->requests,
- GINT_TO_POINTER (monitor_id));
- g_return_if_fail (monitor != NULL);
-
- watch->priv->funcs.suspend (monitor);
-}
-
-
-void
-moo_file_watch_resume_monitor (MooFileWatch *watch,
- int monitor_id)
-{
- Monitor *monitor;
-
- g_return_if_fail (MOO_IS_FILE_WATCH (watch));
-
- monitor = g_hash_table_lookup (watch->priv->requests,
- GINT_TO_POINTER (monitor_id));
- g_return_if_fail (monitor != NULL);
-
- watch->priv->funcs.resume (monitor);
-}
-
-
-void
-moo_file_watch_cancel_monitor (MooFileWatch *watch,
- int monitor_id)
-{
- Monitor *monitor;
-
- g_return_if_fail (MOO_IS_FILE_WATCH (watch));
-
- monitor = g_hash_table_lookup (watch->priv->requests,
- GINT_TO_POINTER (monitor_id));
- g_return_if_fail (monitor != NULL);
-
- watch->priv->funcs.delete (watch, monitor);
- watch->priv->monitors = g_slist_remove (watch->priv->monitors, monitor);
- g_hash_table_remove (watch->priv->requests,
- GINT_TO_POINTER (monitor_id));
-}
-
-
static void
-emit_event (MooFileWatch *watch,
- MooFileWatchEvent *event)
+moo_file_event_free (MooFileEvent *event)
{
- DEBUG_PRINT ("watch %p, monitor %d: event %s for %s",
- watch, event->monitor_id,
- event_code_strings[event->code],
- event->filename ? event->filename : "");
- g_signal_emit (watch, signals[EVENT], 0, event);
+ if (event)
+ {
+ if (event->error)
+ g_error_free (event->error);
+ g_free (event->filename);
+ g_free (event);
+ }
+}
+
+GType
+moo_file_event_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type)
+ type = g_boxed_type_register_static ("MooFileEvent",
+ (GBoxedCopyFunc) moo_file_event_copy,
+ (GBoxedFreeFunc) moo_file_event_free);
+
+ return type;
}
-MooFileWatch *
-moo_file_watch_new (GError **error)
+GType
+moo_file_event_code_get_type (void)
{
- MooFileWatch *watch;
+ static GType type = 0;
- watch = MOO_FILE_WATCH (g_object_new (MOO_TYPE_FILE_WATCH, NULL));
-
- if (!watch->priv->funcs.start (watch, error))
+ if (!type)
{
- g_object_unref (watch);
- return NULL;
+ static const GEnumValue values[] = {
+ { MOO_FILE_EVENT_CHANGED, (char*) "MOO_FILE_EVENT_CHANGED", (char*) "changed"},
+ { MOO_FILE_EVENT_DELETED, (char*) "MOO_FILE_EVENT_DELETED", (char*) "deleted"},
+ { MOO_FILE_EVENT_ERROR, (char*) "MOO_FILE_EVENT_ERROR", (char*) "error"},
+ { 0, NULL, NULL }
+ };
+
+ type = g_enum_register_static ("MooFileEventCode", values);
}
- watch->priv->alive = TRUE;
- return watch;
+ return type;
}
@@ -502,21 +348,180 @@ gboolean
moo_file_watch_close (MooFileWatch *watch,
GError **error)
{
- g_return_val_if_fail (MOO_IS_FILE_WATCH (watch), FALSE);
+ GSList *monitors;
- if (!watch->priv->alive)
+ g_return_val_if_fail (watch != NULL, FALSE);
+
+ if (!watch->alive)
return TRUE;
- watch->priv->alive = FALSE;
+ watch->alive = FALSE;
+ monitors = watch->monitors;
+ watch->monitors = NULL;
- while (watch->priv->monitors)
+ while (monitors)
{
- watch->priv->funcs.delete (watch, watch->priv->monitors->data);
- watch->priv->monitors =
- g_slist_delete_link (watch->priv->monitors, watch->priv->monitors);
+ Monitor *mon = monitors->data;
+
+ if (watch_funcs.stop_monitor)
+ watch_funcs.stop_monitor (watch, mon);
+
+ monitor_free (mon);
+ monitors = g_slist_delete_link (monitors, monitors);
}
- return watch->priv->funcs.shutdown (watch, error);
+ return watch_funcs.shutdown (watch, error);
+}
+
+
+guint
+moo_file_watch_create_monitor (MooFileWatch *watch,
+ const char *filename,
+ MooFileWatchCallback callback,
+ gpointer data,
+ GDestroyNotify notify,
+ GError **error)
+{
+ Monitor *monitor;
+
+ g_return_val_if_fail (watch != NULL, 0);
+ g_return_val_if_fail (filename != NULL, 0);
+ g_return_val_if_fail (callback != NULL, 0);
+
+ if (!watch->alive)
+ {
+ g_set_error (error, MOO_FILE_WATCH_ERROR,
+ MOO_FILE_WATCH_ERROR_CLOSED,
+ "MooFileWatch %d closed",
+ watch->id);
+ return FALSE;
+ }
+
+ monitor = monitor_new (watch, filename, callback, data, notify);
+
+ if (!watch_funcs.start_monitor (watch, monitor, error))
+ {
+ monitor_free (monitor);
+ return 0;
+ }
+
+ monitor->alive = TRUE;
+ watch->monitors = g_slist_prepend (watch->monitors, monitor);
+ g_hash_table_insert (watch->requests, GUINT_TO_POINTER (monitor->id), monitor);
+
+ DEBUG_PRINT ("created monitor for '%s'", monitor->filename);
+
+ return monitor->id;
+}
+
+
+void
+moo_file_watch_cancel_monitor (MooFileWatch *watch,
+ guint monitor_id)
+{
+ Monitor *monitor;
+
+ g_return_if_fail (watch != NULL);
+
+ monitor = g_hash_table_lookup (watch->requests,
+ GUINT_TO_POINTER (monitor_id));
+ g_return_if_fail (monitor != NULL);
+
+ watch->monitors = g_slist_remove (watch->monitors, monitor);
+ g_hash_table_remove (watch->requests, GUINT_TO_POINTER (monitor->id));
+
+ if (monitor->alive && watch_funcs.stop_monitor)
+ watch_funcs.stop_monitor (watch, monitor);
+
+ monitor_free (monitor);
+}
+
+
+void
+moo_file_watch_suspend_monitor (MooFileWatch *watch,
+ guint monitor_id)
+{
+ Monitor *monitor;
+
+ g_return_if_fail (watch != NULL);
+
+ monitor = g_hash_table_lookup (watch->requests,
+ GUINT_TO_POINTER (monitor_id));
+ g_return_if_fail (monitor != NULL);
+
+ if (monitor->alive && !monitor->suspended)
+ {
+ if (!watch_funcs.suspend_monitor || watch_funcs.suspend_monitor (watch, monitor))
+ monitor->suspended = TRUE;
+ }
+}
+
+
+void
+moo_file_watch_resume_monitor (MooFileWatch *watch,
+ guint monitor_id)
+{
+ Monitor *monitor;
+
+ g_return_if_fail (watch != NULL);
+
+ monitor = g_hash_table_lookup (watch->requests,
+ GUINT_TO_POINTER (monitor_id));
+ g_return_if_fail (monitor != NULL);
+
+ if (monitor->alive && monitor->suspended)
+ {
+ if (!watch_funcs.resume_monitor || watch_funcs.resume_monitor (watch, monitor))
+ monitor->suspended = FALSE;
+ }
+}
+
+
+static void
+moo_file_watch_emit_event (MooFileWatch *watch,
+ MooFileEvent *event,
+ Monitor *monitor)
+{
+ moo_file_watch_ref (watch);
+
+ if (!monitor->suspended || event->code == MOO_FILE_EVENT_ERROR)
+ monitor->callback (watch, event, monitor->data);
+
+ moo_file_watch_unref (watch);
+}
+
+
+static Monitor *
+monitor_new (MooFileWatch *watch,
+ const char *filename,
+ MooFileWatchCallback callback,
+ gpointer data,
+ GDestroyNotify notify)
+{
+ Monitor *mon;
+
+ mon = g_new0 (Monitor, 1);
+ mon->watch = watch;
+ mon->filename = g_strdup (filename);
+
+ mon->callback = callback;
+ mon->notify = notify;
+ mon->data = data;
+
+ return mon;
+}
+
+
+static void
+monitor_free (Monitor *monitor)
+{
+ if (monitor)
+ {
+ if (monitor->notify)
+ monitor->notify (monitor->data);
+ g_free (monitor->filename);
+ g_free (monitor);
+ }
}
@@ -555,14 +560,14 @@ watch_fam_start (MooFileWatch *watch,
{
GIOChannel *fam_socket;
- if (FAMOpen (&watch->priv->fam_connection))
+ if (FAMOpen (&watch->fam_connection) != 0)
RETURN_FAM_ERROR (FAMOpen, error, FALSE);
- fam_socket = g_io_channel_unix_new (watch->priv->fam_connection.fd);
- watch->priv->fam_connection_watch =
+ fam_socket = g_io_channel_unix_new (watch->fam_connection.fd);
+ watch->fam_connection_watch =
g_io_add_watch_full (fam_socket, MOO_FAM_SOCKET_WATCH_PRIORITY,
- G_IO_IN | G_IO_PRI | G_IO_PRI | G_IO_HUP,
- (GIOFunc) read_fam_events, watch, NULL);
+ G_IO_IN | G_IO_PRI | G_IO_HUP,
+ (GIOFunc) read_fam_events, watch, NULL);
g_io_channel_unref (fam_socket);
return TRUE;
@@ -573,164 +578,137 @@ static gboolean
watch_fam_shutdown (MooFileWatch *watch,
GError **error)
{
- if (watch->priv->fam_connection_watch)
- g_source_remove (watch->priv->fam_connection_watch);
+ if (watch->fam_connection_watch)
+ g_source_remove (watch->fam_connection_watch);
- if (FAMClose (&watch->priv->fam_connection))
+ if (FAMClose (&watch->fam_connection))
RETURN_FAM_ERROR (FAMOpen, error, FALSE);
else
return TRUE;
}
-static Monitor *
-monitor_fam_create (MooFileWatch *watch,
- MonitorType type,
- const char *filename,
- gpointer data,
- int *request,
- GError **error)
+static gboolean
+watch_fam_start_monitor (MooFileWatch *watch,
+ Monitor *monitor,
+ GError **error)
{
FAMRequest fr;
int result;
- Monitor *monitor;
- g_return_val_if_fail (filename != NULL, FALSE);
+ g_return_val_if_fail (monitor->filename != NULL, FALSE);
- if (type == MONITOR_DIR)
- result = FAMMonitorDirectory (&watch->priv->fam_connection,
- filename, &fr, data);
+ monitor->isdir = g_file_test (monitor->filename, G_FILE_TEST_IS_DIR) != 0;
+
+ if (monitor->isdir)
+ result = FAMMonitorDirectory (&watch->fam_connection,
+ monitor->filename, &fr,
+ NULL);
else
- result = FAMMonitorFile (&watch->priv->fam_connection,
- filename, &fr, data);
+ result = FAMMonitorFile (&watch->fam_connection,
+ monitor->filename, &fr,
+ NULL);
- if (result)
+ if (result != 0)
{
DEBUG_PRINT ("Connection %d: creating monitor for '%s' failed",
- watch->priv->fam_connection.fd, filename);
- if (type == MONITOR_DIR)
- RETURN_FAM_ERROR (FAMMonitorDirectory, error, NULL);
+ watch->fam_connection.fd, monitor->filename);
+
+ if (monitor->isdir)
+ RETURN_FAM_ERROR (FAMMonitorDirectory, error, FALSE);
else
- RETURN_FAM_ERROR (FAMMonitorFile, error, NULL);
+ RETURN_FAM_ERROR (FAMMonitorFile, error, FALSE);
}
else
{
DEBUG_PRINT ("Connection %d: created monitor %d for %s '%s'",
- watch->priv->fam_connection.fd, fr.reqnum,
- type == MONITOR_DIR ? "directory" : "file",
- filename);
+ watch->fam_connection.fd, fr.reqnum,
+ monitor->isdir ? "directory" : "file",
+ monitor->filename);
}
- if (request)
- *request = fr.reqnum;
-
- monitor = g_new0 (Monitor, 1);
-
- monitor->parent = watch;
- monitor->type = type;
- monitor->filename = g_strdup (filename);
- monitor->user_data = data;
- monitor->request = fr.reqnum;
- monitor->suspended = FALSE;
-
- return monitor;
+ monitor->id = fr.reqnum;
+ return TRUE;
}
-static void
-monitor_fam_suspend (Monitor *monitor)
+static gboolean
+watch_fam_suspend_monitor (MooFileWatch *watch,
+ Monitor *monitor)
{
FAMRequest fr;
int result;
- g_return_if_fail (monitor != NULL);
+ g_return_val_if_fail (monitor != NULL, FALSE);
- if (monitor->suspended)
- return;
+ fr.reqnum = monitor->id;
- fr.reqnum = monitor->request;
+ result = FAMSuspendMonitor (&watch->fam_connection, &fr);
- result = FAMSuspendMonitor (&monitor->parent->priv->fam_connection, &fr);
-
- if (result)
+ if (result != 0)
{
- DEBUG_PRINT ("Connection %d: FAMSuspendMonitor for %s '%s' failed",
- monitor->parent->priv->fam_connection.fd,
- monitor->type == MONITOR_DIR ? "directory" : "file",
+ DEBUG_PRINT ("Connection %d: FAMSuspendMonitor for '%s' failed",
+ watch->fam_connection.fd,
monitor->filename);
- return;
}
else
{
- DEBUG_PRINT ("Connection %d: suspended monitor %d for %s '%s'",
- monitor->parent->priv->fam_connection.fd,
- monitor->request,
- monitor->type == MONITOR_DIR ? "directory" : "file",
+ DEBUG_PRINT ("Connection %d: suspended monitor for '%s'",
+ watch->fam_connection.fd,
monitor->filename);
}
- monitor->suspended = TRUE;
+ return result == 0;
}
-static void
-monitor_fam_resume (Monitor *monitor)
+static gboolean
+watch_fam_resume_monitor (MooFileWatch *watch,
+ Monitor *monitor)
{
FAMRequest fr;
int result;
- g_return_if_fail (monitor != NULL);
+ g_return_val_if_fail (monitor != NULL, FALSE);
- if (!monitor->suspended)
- return;
+ fr.reqnum = monitor->id;
- fr.reqnum = monitor->request;
+ result = FAMResumeMonitor (&watch->fam_connection, &fr);
- result = FAMResumeMonitor (&monitor->parent->priv->fam_connection, &fr);
-
- if (result)
+ if (result != 0)
{
- DEBUG_PRINT ("Connection %d: FAMResumeMonitor for %s '%s' failed",
- monitor->parent->priv->fam_connection.fd,
- monitor->type == MONITOR_DIR ? "directory" : "file",
+ DEBUG_PRINT ("Connection %d: FAMResumeMonitor for '%s' failed",
+ watch->fam_connection.fd,
monitor->filename);
- return;
}
else
{
- DEBUG_PRINT ("Connection %d: resumed monitor %d for %s '%s'",
- monitor->parent->priv->fam_connection.fd,
- monitor->request,
- monitor->type == MONITOR_DIR ? "directory" : "file",
+ DEBUG_PRINT ("Connection %d: resumed monitor for '%s'",
+ watch->fam_connection.fd,
monitor->filename);
}
- monitor->suspended = FALSE;
+ return result == 0;
}
static void
-monitor_fam_delete (G_GNUC_UNUSED MooFileWatch *watch,
- Monitor *monitor)
+watch_fam_stop_monitor (MooFileWatch *watch,
+ Monitor *monitor)
{
FAMRequest fr;
int result;
+
g_return_if_fail (monitor != NULL);
- fr.reqnum = monitor->request;
+ fr.reqnum = monitor->id;
- result = FAMCancelMonitor (&monitor->parent->priv->fam_connection, &fr);
+ result = FAMCancelMonitor (&watch->fam_connection, &fr);
- if (result)
- {
- DEBUG_PRINT ("Connection %d: FAMCancelMonitor for %s '%s' failed",
- monitor->parent->priv->fam_connection.fd,
- monitor->type == MONITOR_DIR ? "directory" : "file",
+ if (result != 0)
+ DEBUG_PRINT ("Connection %d: FAMCancelMonitor for '%s' failed",
+ watch->fam_connection.fd,
monitor->filename);
- }
-
- g_free (monitor->filename);
- g_free (monitor);
}
@@ -741,27 +719,19 @@ read_fam_events (G_GNUC_UNUSED GIOChannel *source,
{
GError *error = NULL;
int result;
- FAMConnection *connection = &watch->priv->fam_connection;
+ FAMConnection *connection = &watch->fam_connection;
gboolean retval = TRUE;
- g_object_ref (watch);
+ moo_file_watch_ref (watch);
- if (condition & (G_IO_ERR | G_IO_HUP))
+ if (!watch->alive || condition & (G_IO_ERR | G_IO_HUP))
{
- DEBUG_PRINT ("Connection %d: FAM socket broke",
- connection->fd);
+ g_warning ("Connection %d: broken FAM socket", connection->fd);
- g_set_error (&error, MOO_FILE_WATCH_ERROR,
- MOO_FILE_WATCH_ERROR_FAILED,
- "Connection to FAM is broken");
- g_signal_emit (watch, signals[ERROR_SIGNAL], 0, error);
- g_error_free (error);
- error = NULL;
-
- if (!moo_file_watch_close (watch, &error))
+ if (watch->alive && !moo_file_watch_close (watch, &error))
{
- DEBUG_PRINT ("%s: error in moo_file_watch_close()", G_STRLOC);
- DEBUG_PRINT ("%s: %s", G_STRLOC, error->message);
+ g_warning ("%s: error in moo_file_watch_close()", G_STRLOC);
+ g_warning ("%s: %s", G_STRLOC, error->message);
g_error_free (error);
}
@@ -772,8 +742,9 @@ read_fam_events (G_GNUC_UNUSED GIOChannel *source,
while ((result = FAMPending (connection)))
{
FAMEvent fe;
- MooFileWatchEvent event;
+ MooFileEvent event;
gboolean emit = TRUE;
+ Monitor *monitor;
if (result < 0)
{
@@ -788,14 +759,14 @@ read_fam_events (G_GNUC_UNUSED GIOChannel *source,
if (error)
{
- g_signal_emit (watch, signals[ERROR_SIGNAL], 0, error);
+ g_warning ("Connection %d: error: %s", connection->fd, error->message);
g_error_free (error);
error = NULL;
if (!moo_file_watch_close (watch, &error))
{
- DEBUG_PRINT ("%s: error in moo_file_watch_close()", G_STRLOC);
- DEBUG_PRINT ("%s: %s", G_STRLOC, error->message);
+ g_warning ("%s: error in moo_file_watch_close()", G_STRLOC);
+ g_warning ("%s: %s", G_STRLOC, error->message);
g_error_free (error);
}
@@ -803,25 +774,31 @@ read_fam_events (G_GNUC_UNUSED GIOChannel *source,
goto out;
}
+ monitor = g_hash_table_lookup (watch->requests, GUINT_TO_POINTER ((guint) fe.fr.reqnum));
+
+ if (!monitor || monitor->suspended)
+ continue;
+
/* TODO: check monitor here */
- event.monitor_id = fe.fr.reqnum;
+ event.monitor_id = monitor->id;
event.filename = fe.filename;
- event.data = fe.userdata;
event.error = NULL;
switch (fe.code)
{
case FAMChanged:
- event.code = MOO_FILE_WATCH_EVENT_CHANGED;
+ case FAMCreated:
+ event.code = MOO_FILE_EVENT_CHANGED;
+ event.filename = monitor->filename;
break;
case FAMDeleted:
- event.code = MOO_FILE_WATCH_EVENT_DELETED;
- break;
- case FAMCreated:
- event.code = MOO_FILE_WATCH_EVENT_CREATED;
+ event.code = MOO_FILE_EVENT_DELETED;
break;
+
case FAMMoved:
- event.code = MOO_FILE_WATCH_EVENT_MOVED;
+ /* XXX never happens with FAM, what about gamin? */
+ event.code = MOO_FILE_EVENT_CHANGED;
+ event.filename = monitor->filename;
break;
case FAMStartExecuting:
@@ -838,13 +815,11 @@ read_fam_events (G_GNUC_UNUSED GIOChannel *source,
}
if (emit)
- {
- emit_event (watch, &event);
- }
+ moo_file_watch_emit_event (watch, &event, monitor);
}
out:
- g_object_unref (watch);
+ moo_file_watch_ref (watch);
return retval;
}
@@ -856,18 +831,20 @@ out:
/* stat()
*/
-#define MOO_STAT_PRIORITY G_PRIORITY_DEFAULT
-#define MOO_STAT_TIMEOUT 500
+#ifdef WANT_STAT_MONITOR
+
+#define MOO_STAT_PRIORITY G_PRIORITY_DEFAULT
+#define MOO_STAT_TIMEOUT 500
static MooFileWatchError errno_to_file_error (int code);
static gboolean do_stat (MooFileWatch *watch);
static gboolean
-watch_stat_start (MooFileWatch *watch,
+watch_stat_start (MooFileWatch *watch,
G_GNUC_UNUSED GError **error)
{
- watch->priv->stat_timeout =
+ watch->stat_timeout =
g_timeout_add_full (MOO_STAT_PRIORITY,
MOO_STAT_TIMEOUT,
(GSourceFunc) do_stat,
@@ -877,103 +854,58 @@ watch_stat_start (MooFileWatch *watch,
static gboolean
-watch_stat_shutdown (MooFileWatch *watch,
+watch_stat_shutdown (MooFileWatch *watch,
G_GNUC_UNUSED GError **error)
{
- if (watch->priv->stat_timeout)
- g_source_remove (watch->priv->stat_timeout);
- watch->priv->stat_timeout = 0;
+ if (watch->stat_timeout)
+ g_source_remove (watch->stat_timeout);
+ watch->stat_timeout = 0;
return TRUE;
}
-static Monitor *
-monitor_stat_create (MooFileWatch *watch,
- MonitorType type,
- const char *filename,
- gpointer data,
- int *request,
- GError **error)
+static gboolean
+watch_stat_start_monitor (MooFileWatch *watch,
+ Monitor *monitor,
+ GError **error)
{
- Monitor *monitor;
struct stat buf;
- g_return_val_if_fail (MOO_IS_FILE_WATCH (watch), NULL);
- g_return_val_if_fail (filename != NULL, NULL);
+ g_return_val_if_fail (watch != NULL, FALSE);
+ g_return_val_if_fail (monitor->filename != NULL, FALSE);
errno = 0;
- if (g_stat (filename, &buf) != 0)
+ if (g_stat (monitor->filename, &buf) != 0)
{
int saved_errno = errno;
g_set_error (error, MOO_FILE_WATCH_ERROR,
errno_to_file_error (saved_errno),
"stat: %s", g_strerror (saved_errno));
- return NULL;
+ return FALSE;
}
- if (type == MONITOR_DIR && !S_ISDIR (buf.st_mode))
+ monitor->isdir = S_ISDIR (buf.st_mode) != 0;
+
+#ifdef __WIN32__
+ if (monitor->isdir) /* it's fatal on windows */
{
- char *display_name = g_filename_display_name (filename);
+ char *display_name = g_filename_display_name (monitor->filename);
g_set_error (error, MOO_FILE_WATCH_ERROR,
- MOO_FILE_WATCH_ERROR_NOT_DIR,
- "%s is not a directory", display_name);
- g_free (display_name);
- return NULL;
- }
- else if (type == MONITOR_FILE && S_ISDIR (buf.st_mode)) /* it's fatal on windows */
- {
- char *display_name = g_filename_display_name (filename);
- g_set_error (error, MOO_FILE_WATCH_ERROR,
- MOO_FILE_WATCH_ERROR_IS_DIR,
+ MOO_FILE_WATCH_ERROR_FAILED,
"%s is a directory", display_name);
g_free (display_name);
- return NULL;
+ return FALSE;
}
+#endif
- DEBUG_PRINT ("created monitor for '%s'", filename);
-
- monitor = g_new0 (Monitor, 1);
- monitor->parent = watch;
- monitor->type = type;
- monitor->filename = g_strdup (filename);
- monitor->user_data = data;
- monitor->request = ++last_monitor_id;
- monitor->suspended = FALSE;
+ if (!++last_monitor_id)
+ ++last_monitor_id;
+ monitor->id = last_monitor_id;
memcpy (&monitor->statbuf, &buf, sizeof (buf));
- if (request)
- *request = monitor->request;
-
- return monitor;
-}
-
-
-static void
-monitor_stat_suspend (Monitor *monitor)
-{
- g_return_if_fail (monitor != NULL);
- monitor->suspended = TRUE;
-}
-
-
-static void
-monitor_stat_resume (Monitor *monitor)
-{
- g_return_if_fail (monitor != NULL);
- monitor->suspended = FALSE;
-}
-
-
-static void
-monitor_stat_delete (G_GNUC_UNUSED MooFileWatch *watch,
- Monitor *monitor)
-{
- g_return_if_fail (monitor != NULL);
- DEBUG_PRINT ("removing monitor for '%s'", monitor->filename);
- g_free (monitor->filename);
- g_free (monitor);
+ return TRUE;
}
@@ -983,70 +915,80 @@ do_stat (MooFileWatch *watch)
GSList *l, *list, *to_remove = NULL;
gboolean result = TRUE;
- g_return_val_if_fail (MOO_IS_FILE_WATCH (watch), FALSE);
+ g_return_val_if_fail (watch != NULL, FALSE);
- g_object_ref (watch);
+ moo_file_watch_ref (watch);
- if (!watch->priv->monitors)
+ if (!watch->monitors)
goto out;
- list = g_slist_copy (watch->priv->monitors);
+ list = g_slist_copy (watch->monitors);
for (l = list; l != NULL; l = l->next)
{
- MooFileWatchEvent event;
+ gboolean do_emit = FALSE;
+ MooFileEvent event;
Monitor *monitor = l->data;
time_t old;
g_assert (monitor != NULL);
- if (!g_hash_table_lookup (watch->priv->requests,
- GINT_TO_POINTER (monitor->request)))
+ if (!g_hash_table_lookup (watch->requests, GUINT_TO_POINTER (monitor->id)))
continue;
- if (monitor->suspended)
+ if (monitor->suspended || !monitor->alive)
continue;
old = monitor->statbuf.st_mtime;
errno = 0;
+ event.monitor_id = monitor->id;
+ event.filename = monitor->filename;
+ event.error = NULL;
+
if (g_stat (monitor->filename, &monitor->statbuf) != 0)
{
- event.code = MOO_FILE_WATCH_EVENT_DELETED;
- event.monitor_id = monitor->request;
- event.filename = monitor->filename;
- event.data = monitor->user_data;
+ if (errno == ENOENT)
+ {
+ event.code = MOO_FILE_EVENT_DELETED;
+ to_remove = g_slist_prepend (to_remove, GUINT_TO_POINTER (monitor->id));
+ }
+ else
+ {
+ int err = errno;
+ event.code = MOO_FILE_EVENT_ERROR;
+ g_set_error (&event.error, MOO_FILE_WATCH_ERROR,
+ errno_to_file_error (err),
+ "stat failed: %s",
+ g_strerror (err));
+ monitor->alive = FALSE;
+ }
- DEBUG_PRINT ("'%s' deleted", monitor->filename);
-
- to_remove = g_slist_prepend (to_remove,
- GINT_TO_POINTER (monitor->request));
-
- emit_event (watch, &event);
+ do_emit = TRUE;
}
else if (monitor->statbuf.st_mtime > old)
{
- event.code = MOO_FILE_WATCH_EVENT_CHANGED;
- event.monitor_id = monitor->request;
- event.filename = monitor->filename;
- event.data = monitor->user_data;
-
- DEBUG_PRINT ("'%s' changed", monitor->filename);
-
- emit_event (watch, &event);
+ event.code = MOO_FILE_EVENT_CHANGED;
+ do_emit = TRUE;
}
+
+ if (do_emit)
+ moo_file_watch_emit_event (watch, &event, monitor);
+
+ if (event.error)
+ g_error_free (event.error);
}
for (l = to_remove; l != NULL; l = l->next)
- if (g_hash_table_lookup (watch->priv->requests, GINT_TO_POINTER (l->data)))
- moo_file_watch_cancel_monitor (watch, GPOINTER_TO_INT (l->data));
+ if (g_hash_table_lookup (watch->requests, GUINT_TO_POINTER (l->data)))
+ moo_file_watch_cancel_monitor (watch, GPOINTER_TO_UINT (l->data));
g_slist_free (to_remove);
g_slist_free (list);
out:
- g_object_unref (watch);
+ moo_file_watch_unref (watch);
return result;
}
@@ -1076,6 +1018,7 @@ errno_to_file_error (int code)
}
+#endif /* WANT_STAT_MONITOR */
/*****************************************************************************/
/* win32
@@ -1247,7 +1190,7 @@ fam_thread_check_dir (FAMThread *thr,
if (g_stat (thr->watches[idx].path, &buf) != 0 &&
errno == ENOENT)
{
- fam_thread_event (MOO_FILE_WATCH_EVENT_DELETED,
+ fam_thread_event (MOO_FILE_EVENT_DELETED,
FALSE, NULL,
thr->watches[idx].watch_id,
thr->watches[idx].request);
@@ -1257,7 +1200,7 @@ fam_thread_check_dir (FAMThread *thr,
}
else
{
- fam_thread_event (MOO_FILE_WATCH_EVENT_CHANGED,
+ fam_thread_event (MOO_FILE_EVENT_CHANGED,
FALSE, NULL,
thr->watches[idx].watch_id,
thr->watches[idx].request);
@@ -1386,7 +1329,8 @@ find_watch (guint id)
for (l = fam->watches; l != NULL; l = l->next)
{
MooFileWatch *watch = l->data;
- if (watch->priv->id == id)
+
+ if (watch->id == id)
return watch;
}
@@ -1398,7 +1342,7 @@ do_event (FAMEvent *event)
{
MooFileWatch *watch;
Monitor *monitor;
- MooFileWatchEvent watch_event;
+ MooFileEvent watch_event;
watch = find_watch (event->watch_id);
@@ -1408,7 +1352,7 @@ do_event (FAMEvent *event)
return;
}
- monitor = g_hash_table_lookup (watch->priv->requests,
+ monitor = g_hash_table_lookup (watch->requests,
GUINT_TO_POINTER (event->request));
if (!monitor)
@@ -1419,12 +1363,11 @@ do_event (FAMEvent *event)
watch_event.monitor_id = event->request;
watch_event.filename = monitor->filename;
- watch_event.data = monitor->user_data;
watch_event.error = NULL;
if (event->error)
{
- watch_event.code = MOO_FILE_WATCH_EVENT_ERROR;
+ watch_event.code = MOO_FILE_EVENT_ERROR;
g_set_error (&watch_event.error, MOO_FILE_WATCH_ERROR,
event->code,
event->msg ? event->msg : "FAILED");
@@ -1436,7 +1379,7 @@ do_event (FAMEvent *event)
watch_event.code = event->code;
}
- emit_event (watch, &watch_event);
+ moo_file_watch_emit_event (watch, &watch_event, monitor);
if (watch_event.error)
g_error_free (watch_event.error);
@@ -1544,9 +1487,8 @@ watch_win32_start (MooFileWatch *watch,
return FALSE;
}
- watch->priv->id = ++last_watch_id;
fam->watches = g_slist_prepend (fam->watches, watch);
- DEBUG_PRINT ("started watch %d", watch->priv->id);
+ DEBUG_PRINT ("started watch %d", watch->id);
return TRUE;
}
@@ -1560,123 +1502,75 @@ watch_win32_shutdown (MooFileWatch *watch,
}
-static Monitor *
-monitor_win32_create (MooFileWatch *watch,
- MonitorType type,
- const char *filename,
- gpointer data,
- int *request,
- GError **error)
+static gboolean
+watch_win32_start_monitor (MooFileWatch *watch,
+ Monitor *monitor,
+ GError **error)
{
- Monitor *monitor;
struct stat buf;
- g_return_val_if_fail (MOO_IS_FILE_WATCH (watch), NULL);
- g_return_val_if_fail (filename != NULL, FALSE);
-
- if (type == MONITOR_FILE)
- return monitor_stat_create (watch, type, filename, data, request, error);
+ g_return_val_if_fail (watch != NULL, FALSE);
+ g_return_val_if_fail (monitor->filename != NULL, FALSE);
errno = 0;
- if (g_stat (filename, &buf) != 0)
+ if (g_stat (monitor->filename, &buf) != 0)
{
int saved_errno = errno;
g_set_error (error, MOO_FILE_WATCH_ERROR,
errno_to_file_error (saved_errno),
"stat: %s", g_strerror (saved_errno));
- return NULL;
+ return FALSE;
}
- if (type == MONITOR_DIR && !S_ISDIR (buf.st_mode))
- {
- char *display_name = g_filename_display_name (filename);
- g_set_error (error, MOO_FILE_WATCH_ERROR,
- MOO_FILE_WATCH_ERROR_NOT_DIR,
- "%s is not a directory", display_name);
- g_free (display_name);
- return NULL;
- }
- else if (type == MONITOR_FILE && S_ISDIR (buf.st_mode)) /* it's fatal on windows */
- {
- char *display_name = g_filename_display_name (filename);
- g_set_error (error, MOO_FILE_WATCH_ERROR,
- MOO_FILE_WATCH_ERROR_IS_DIR,
- "%s is a directory", display_name);
- g_free (display_name);
- return NULL;
- }
+ monitor->isdir = S_ISDIR (buf.st_mode) != 0;
- DEBUG_PRINT ("created monitor for '%s'", filename);
+ if (!monitor->isdir)
+ return watch_stat_start_monitor (watch, monitor, error);
- monitor = g_new0 (Monitor, 1);
- monitor->parent = watch;
- monitor->type = type;
- monitor->filename = g_strdup (filename);
- monitor->user_data = data;
- monitor->request = ++last_monitor_id;
- monitor->suspended = FALSE;
+ DEBUG_PRINT ("created monitor for '%s'", monitor->filename);
- if (request)
- *request = monitor->request;
+ monitor->id = ++last_monitor_id;
- fam_thread_command (COMMAND_ADD_PATH, filename, watch->priv->id, monitor->request);
+ fam_thread_command (COMMAND_ADD_PATH, monitor->filename, watch->id, monitor->id);
- return monitor;
+ return TRUE;
}
-static void
-monitor_win32_suspend (Monitor *monitor)
+static gboolean
+watch_win32_suspend_monitor (MooFileWatch *watch,
+ Monitor *monitor)
{
- g_return_if_fail (monitor != NULL);
-
- if (monitor->suspended)
- return;
-
- if (monitor->type == MONITOR_FILE)
- {
- monitor_stat_suspend (monitor);
- return;
- }
-
+ g_return_val_if_fail (watch != NULL, FALSE);
+ g_return_val_if_fail (monitor != NULL, FALSE);
g_critical ("%s: implement me", G_STRFUNC);
+ return FALSE;
}
-static void
-monitor_win32_resume (Monitor *monitor)
+static gboolean
+watch_win32_resume_monitor (MooFileWatch *watch,
+ Monitor *monitor)
{
- g_return_if_fail (monitor != NULL);
-
- if (!monitor->suspended)
- return;
-
- if (monitor->type == MONITOR_FILE)
- {
- monitor_stat_resume (monitor);
- return;
- }
-
+ g_return_val_if_fail (watch != NULL, FALSE);
+ g_return_val_if_fail (monitor != NULL, FALSE);
g_critical ("%s: implement me", G_STRFUNC);
+ return FALSE;
}
static void
-monitor_win32_delete (MooFileWatch *watch,
- Monitor *monitor)
+watch_win32_stop_monitor (MooFileWatch *watch,
+ Monitor *monitor)
{
g_return_if_fail (monitor != NULL);
- if (monitor->type == MONITOR_FILE)
+ if (monitor->isdir)
{
- monitor_stat_delete (watch, monitor);
- return;
+ DEBUG_PRINT ("removing monitor for '%s'", monitor->filename);
+ fam_thread_command (COMMAND_REMOVE_PATH, monitor->filename,
+ watch->id, monitor->id);
}
-
- DEBUG_PRINT ("removing monitor for '%s'", monitor->filename);
- fam_thread_command (COMMAND_REMOVE_PATH, monitor->filename, watch->priv->id, monitor->request);
- g_free (monitor->filename);
- g_free (monitor);
}
#endif /* __WIN32__ */
diff --git a/moo/mooutils/moofilewatch.h b/moo/mooutils/moofilewatch.h
index 58d45fef..92e78cc6 100644
--- a/moo/mooutils/moofilewatch.h
+++ b/moo/mooutils/moofilewatch.h
@@ -40,99 +40,60 @@ typedef enum
GQuark moo_file_watch_error_quark (void);
-#define MOO_TYPE_FILE_WATCH (moo_file_watch_get_type ())
-#define MOO_FILE_WATCH(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MOO_TYPE_FILE_WATCH, MooFileWatch))
-#define MOO_FILE_WATCH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOO_TYPE_FILE_WATCH, MooFileWatchClass))
-#define MOO_IS_FILE_WATCH(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MOO_TYPE_FILE_WATCH))
-#define MOO_IS_FILE_WATCH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOO_TYPE_FILE_WATCH))
-#define MOO_FILE_WATCH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOO_TYPE_FILE_WATCH, MooFileWatchClass))
-
-#define MOO_TYPE_FILE_WATCH_EVENT (moo_file_watch_event_get_type ())
-#define MOO_TYPE_FILE_WATCH_EVENT_CODE (moo_file_watch_event_code_get_type ())
-#define MOO_TYPE_FILE_WATCH_METHOD (moo_file_watch_method_get_type ())
+#define MOO_TYPE_FILE_WATCH (moo_file_watch_get_type ())
+#define MOO_TYPE_FILE_EVENT (moo_file_event_get_type ())
+#define MOO_TYPE_FILE_EVENT_CODE (moo_file_event_code_get_type ())
typedef enum {
- MOO_FILE_WATCH_STAT,
- MOO_FILE_WATCH_FAM,
- MOO_FILE_WATCH_WIN32
-} MooFileWatchMethod;
+ MOO_FILE_EVENT_CHANGED,
+ MOO_FILE_EVENT_DELETED,
+ MOO_FILE_EVENT_ERROR
+} MooFileEventCode;
-/* Stripped FAMEventCode enumeration */
-typedef enum {
- MOO_FILE_WATCH_EVENT_CHANGED = 1,
- MOO_FILE_WATCH_EVENT_DELETED = 2,
- MOO_FILE_WATCH_EVENT_CREATED = 3,
- MOO_FILE_WATCH_EVENT_MOVED = 4,
- MOO_FILE_WATCH_EVENT_ERROR = 5
-} MooFileWatchEventCode;
-
-/* The structure has the same meaning as the FAMEvent
- (it is a simple copy of FAMEvent structure when
- FAM is used). In the case when stat() is used, when
- directory content is changed, MooFileWatch does not
- try to learn what happened, and just emits CHANGED
- event with filename set to directory name.
- */
-struct _MooFileWatchEvent {
- MooFileWatchEventCode code; /* FAMEventCode */
- int monitor_id; /* FAMRequest */
- char *filename;
- GError *error;
- gpointer data;
+struct _MooFileEvent {
+ MooFileEventCode code;
+ guint monitor_id;
+ char *filename;
+ GError *error;
};
typedef struct _MooFileWatch MooFileWatch;
-typedef struct _MooFileWatchPrivate MooFileWatchPrivate;
-typedef struct _MooFileWatchClass MooFileWatchClass;
-typedef struct _MooFileWatchEvent MooFileWatchEvent;
+typedef struct _MooFileEvent MooFileEvent;
-struct _MooFileWatch
-{
- GObject parent;
- MooFileWatchPrivate *priv;
-};
+typedef void (*MooFileWatchCallback) (MooFileWatch *watch,
+ MooFileEvent *event,
+ gpointer user_data);
-struct _MooFileWatchClass
-{
- GObjectClass parent_class;
-
- void (*event) (MooFileWatch *watch,
- MooFileWatchEvent *event);
- void (*error) (MooFileWatch *watch,
- GError *error);
-};
GType moo_file_watch_get_type (void) G_GNUC_CONST;
-GType moo_file_watch_event_get_type (void) G_GNUC_CONST;
-GType moo_file_watch_event_code_get_type (void) G_GNUC_CONST;
-GType moo_file_watch_method_get_type (void) G_GNUC_CONST;
+GType moo_file_event_get_type (void) G_GNUC_CONST;
+GType moo_file_event_code_get_type (void) G_GNUC_CONST;
/* FAMOpen */
MooFileWatch *moo_file_watch_new (GError **error);
+MooFileWatch *moo_file_watch_ref (MooFileWatch *watch);
+void moo_file_watch_unref (MooFileWatch *watch);
+
/* FAMClose */
gboolean moo_file_watch_close (MooFileWatch *watch,
GError **error);
/* FAMMonitorDirectory, FAMMonitorFile */
-int moo_file_watch_monitor_directory (MooFileWatch *watch,
+guint moo_file_watch_create_monitor (MooFileWatch *watch,
const char *filename,
+ MooFileWatchCallback callback,
gpointer data,
+ GDestroyNotify notify,
GError **error);
-int moo_file_watch_monitor_file (MooFileWatch *watch,
- const char *filename,
- gpointer data,
- GError **error);
-
-/* FAMSuspendMonitor, FAMResumeMonitor, FAMCancelMonitor */
-void moo_file_watch_suspend_monitor (MooFileWatch *watch,
- int monitor_id);
-void moo_file_watch_resume_monitor (MooFileWatch *watch,
- int monitor_id);
+/* FAMCancelMonitor */
void moo_file_watch_cancel_monitor (MooFileWatch *watch,
- int monitor_id);
-
-MooFileWatchMethod moo_file_watch_get_method (MooFileWatch *watch);
+ guint monitor_id);
+/* FAMSuspendMonitor, FAMResumeMonitor */
+void moo_file_watch_suspend_monitor (MooFileWatch *watch,
+ guint monitor_id);
+void moo_file_watch_resume_monitor (MooFileWatch *watch,
+ guint monitor_id);
G_END_DECLS