Hi,
Use glib g_object_ref/unref to avoid accessing destroyed logs in g_timeout_add.
$ svn diff
Index: patches/gnome-utils-04-logview-plugin.diff
===================================================================
--- patches/gnome-utils-04-logview-plugin.diff (revision 10425)
+++ patches/gnome-utils-04-logview-plugin.diff (working copy)
@@ -7976,11 +7976,11 @@
+
+#endif /* __LOGVIEW_IFACE_H__ */
+
-Index: gnome-utils-trunk/logview/monitor.c
+Index: gnome-utils/logview/monitor.c
===================================================================
---- gnome-utils-trunk/logview/monitor.c (revision 7356)
-+++ gnome-utils-trunk/logview/monitor.c (working copy)
-@@ -1,98 +1,159 @@
+--- gnome-utils/logview/monitor.c (revision 7378)
++++ gnome-utils/logview/monitor.c (working copy)
+@@ -1,98 +1,156 @@
-/* ----------------------------------------------------------------------
+/* ----------------------------------------------------------------------
@@ -8028,7 +8028,6 @@
+#include "logview-debug.h"
+#define CHECK_FILE_PERIOD 10000
-+static GSList *monitor_list = NULL;
+
void
monitor_stop (Log *log)
@@ -8036,7 +8035,7 @@
- g_return_if_fail (log);
+ GnomeVFSMonitorHandle *mon_handle;
+ LV_MARK;
-+ g_return_if_fail (log);
++ g_assert (LOGVIEW_IS_LOG (log));
- if (log->mon_handle != NULL) {
- gnome_vfs_monitor_cancel (log->mon_handle);
@@ -8048,18 +8047,16 @@
-
- log->monitored = FALSE;
- }
-+ if (g_slist_find (monitor_list, log)) {
-+ monitor_list = g_slist_remove (monitor_list, log);
-+ g_object_get (G_OBJECT (log),
-+ "monitor-handle", &mon_handle, NULL);
-+ if (mon_handle != NULL) {
-+ gnome_vfs_monitor_cancel (mon_handle);
-+ g_object_set (G_OBJECT (log),
-+ "monitor-handle", NULL, NULL);
-+ }
++ g_object_get (G_OBJECT (log),
++ "monitor-handle", &mon_handle, NULL);
++ if (mon_handle != NULL) {
++ gnome_vfs_monitor_cancel (mon_handle);
+ g_object_set (G_OBJECT (log),
-+ "monitoring", FALSE, NULL);
++ "monitor-handle", NULL, NULL);
+ }
++ g_object_set (G_OBJECT (log),
++ "monitoring", FALSE, NULL);
++ g_object_unref (log);
}
static void
@@ -8077,7 +8074,7 @@
+ Log *log = data;
+
+ LV_MARK;
-+ g_assert (log);
++ g_assert (LOGVIEW_IS_LOG (log));
+
+ g_object_get (G_OBJECT (log),
+ "window", &logview,
@@ -8095,7 +8092,9 @@
+/* ----------------------------------------------------------------------
+NAME: monitor_log_was_modified
+DESCRIPTION: Returns true if modified flag in log changed. It also
-+changes the modified flag.
++changes the modified flag. This function is called in unexpected time,
++so the passed in log must be referenced. And only unreferenced when timer
++is invalid.
+---------------------------------------------------------------------- */
+
+static gboolean
@@ -8103,12 +8102,12 @@
+{
+ gboolean monitoring;
+ LV_MARK;
-+ if (g_slist_find (monitor_list, log) == NULL )
-+ return FALSE;
-+ g_return_val_if_fail (LOGVIEW_IS_LOG (log), FALSE);
++ g_assert (LOGVIEW_IS_LOG (log));
+ g_object_get (G_OBJECT (log), "monitoring", &monitoring, NULL);
-+ if (! monitoring)
++ if (! monitoring) {
++ g_object_unref (log);
+ return FALSE;
++ }
+ if (log_has_been_modified (log)) {
+ monitor_callback(NULL, NULL, NULL, 0, log);
+ }
@@ -8135,8 +8134,9 @@
- result = gnome_vfs_tell (log->mon_file_handle, &size);
- log->mon_offset = size;
+ LV_MARK;
-+ g_return_if_fail (log);
++ g_assert (LOGVIEW_IS_LOG (log));
+
++ g_object_ref (log);
+ g_object_get (G_OBJECT (log),
+ "monitorable", &monitorable,
+ "monitor-handle", &mon_handle,
@@ -8144,17 +8144,10 @@
+ NULL);
+ if (!monitorable) {
+ g_free (name);
++ g_object_unref (log);
+ return;
+ }
+
-+ if (g_slist_find (monitor_list, log)) {
-+ g_free (name);
-+ return;
-+ }
-
-- result = gnome_vfs_monitor_add (&(log->mon_handle), log->name,
-- GNOME_VFS_MONITOR_FILE, monitor_callback,
-- log);
+ result = gnome_vfs_monitor_add (&mon_handle, name,
+ GNOME_VFS_MONITOR_FILE,
+ monitor_callback, log);
@@ -8162,7 +8155,8 @@
+ if (result == GNOME_VFS_ERROR_NOT_SUPPORTED) {
+ mon_handle = NULL;
+ g_timeout_add (CHECK_FILE_PERIOD,
-+ (GSourceFunc) monitor_log_was_modified,
log);
++ (GSourceFunc) monitor_log_was_modified,
++ g_object_ref(log));
+ }
+ else {
+ goto gnome_vfs_err;
@@ -8173,6 +8167,14 @@
+ "monitor-handle", mon_handle, NULL);
+ }
+- result = gnome_vfs_monitor_add (&(log->mon_handle), log->name,
+- GNOME_VFS_MONITOR_FILE, monitor_callback,
+- log);
++ g_object_set (G_OBJECT (log),
++ "monitoring", TRUE, NULL);
++ g_free (name);
++ return;
+
- if (result != GNOME_VFS_OK) {
- main = g_strdup (_("This file cannot be monitored."));
- switch (result) {
@@ -8187,12 +8189,7 @@
- gnome_vfs_close (log->mon_file_handle);
- return;
- }
-+ g_object_set (G_OBJECT (log),
-+ "monitoring", TRUE, NULL);
-+ monitor_list = g_slist_append (monitor_list, log);
-+ g_free (name);
-+ return;
-
+-
- log->monitored = TRUE;
+gnome_vfs_err:
+ first = g_strdup (_("Gnome-VFS error."));
@@ -8204,6 +8201,7 @@
+ g_free (first);
+ g_free (second);
+ g_free (name);
++ g_object_unref (log);
}
--
x82120 / +86 10 82618200