Please include the new patch instead of a diff of a patch
unless the change is very very simple and clear from the diff.

Thanks,
Laca

On Thu, 2007-02-01 at 16:00 +0800, Lin Ma wrote:
> 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);
>   }
> 
> 


Reply via email to