[evolution-data-server] Bug 697734 - Memory leak in local calendar backend



commit f8c1f31ca598f0ed37480de0bc73c5171abcd8b8
Author: Matthew Barnes <mbarnes redhat com>
Date:   Thu Apr 11 11:17:58 2013 -0400

    Bug 697734 - Memory leak in local calendar backend
    
    We were leaking an icalproperty while seeding the "revision" D-Bus
    property during instance initialization, because the backend does
    not yet have an icalcomponent to hold the icalproperty.
    
    This commit avoids the leak during instance initialization, but also
    makes sure the "revision" property gets updated once the backend does
    have an icalcomponent.

 calendar/backends/file/e-cal-backend-file.c |   50 +++++++++++++++++++++------
 1 files changed, 39 insertions(+), 11 deletions(-)
---
diff --git a/calendar/backends/file/e-cal-backend-file.c b/calendar/backends/file/e-cal-backend-file.c
index 7f38458..1b0ce3c 100644
--- a/calendar/backends/file/e-cal-backend-file.c
+++ b/calendar/backends/file/e-cal-backend-file.c
@@ -383,11 +383,11 @@ uid_in_use (ECalBackendFile *cbfile,
 static icalproperty *
 get_revision_property (ECalBackendFile *cbfile)
 {
-       ECalBackendFilePrivate *priv;
-       icalproperty           *prop;
+       icalproperty *prop = NULL;
 
-       priv = cbfile->priv;
-       prop = icalcomponent_get_first_property (priv->icalcomp, ICAL_X_PROPERTY);
+       if (cbfile->priv->icalcomp != NULL)
+               prop = icalcomponent_get_first_property (
+                       cbfile->priv->icalcomp, ICAL_X_PROPERTY);
 
        while (prop != NULL) {
                const gchar *name = icalproperty_get_x_name (prop);
@@ -395,7 +395,8 @@ get_revision_property (ECalBackendFile *cbfile)
                if (name && strcmp (name, ECAL_REVISION_X_PROP) == 0)
                        return prop;
 
-               prop = icalcomponent_get_next_property (priv->icalcomp, ICAL_X_PROPERTY);
+               prop = icalcomponent_get_next_property (
+                       cbfile->priv->icalcomp, ICAL_X_PROPERTY);
        }
 
        return NULL;
@@ -420,11 +421,14 @@ make_revision_string (ECalBackendFile *cbfile)
 static icalproperty *
 ensure_revision (ECalBackendFile *cbfile)
 {
-       icalproperty * prop;
+       icalproperty *prop;
+
+       if (cbfile->priv->icalcomp == NULL)
+               return NULL;
 
        prop = get_revision_property (cbfile);
 
-       if (!prop) {
+       if (prop == NULL) {
                gchar *revision = make_revision_string (cbfile);
 
                prop = icalproperty_new (ICAL_X_PROPERTY);
@@ -514,9 +518,14 @@ e_cal_backend_file_get_backend_property (ECalBackend *backend,
 
        } else if (g_str_equal (prop_name, CAL_BACKEND_PROPERTY_REVISION)) {
                icalproperty *prop;
+               const gchar *revision = NULL;
 
+               /* This returns NULL if backend lacks an icalcomp. */
                prop = ensure_revision (E_CAL_BACKEND_FILE (backend));
-               return g_strdup (icalproperty_get_x (prop));
+               if (prop != NULL)
+                       revision = icalproperty_get_x (prop);
+
+               return g_strdup (revision);
        }
 
        /* Chain up to parent's get_backend_property() method. */
@@ -1067,6 +1076,23 @@ free_refresh_data (ECalBackendFile *cbfile)
        g_mutex_unlock (&priv->refresh_lock);
 }
 
+static void
+cal_backend_file_take_icalcomp (ECalBackendFile *cbfile,
+                                icalcomponent *icalcomp)
+{
+       icalproperty *prop;
+
+       g_warn_if_fail (cbfile->priv->icalcomp == NULL);
+       cbfile->priv->icalcomp = icalcomp;
+
+       prop = ensure_revision (cbfile);
+
+       e_cal_backend_notify_property_changed (
+               E_CAL_BACKEND (cbfile),
+               CAL_BACKEND_PROPERTY_REVISION,
+               icalproperty_get_x (prop));
+}
+
 /* Parses an open iCalendar file and loads it into the backend */
 static void
 open_cal (ECalBackendFile *cbfile,
@@ -1097,7 +1123,7 @@ open_cal (ECalBackendFile *cbfile,
                return;
        }
 
-       priv->icalcomp = icalcomp;
+       cal_backend_file_take_icalcomp (cbfile, icalcomp);
        priv->path = uri_to_path (E_CAL_BACKEND (cbfile));
 
        priv->comp_uid_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_object_data);
@@ -1234,7 +1260,7 @@ reload_cal (ECalBackendFile *cbfile,
 
        free_calendar_data (cbfile);
 
-       priv->icalcomp = icalcomp;
+       cal_backend_file_take_icalcomp (cbfile, icalcomp);
 
        priv->comp_uid_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_object_data);
        priv->interval_tree = e_intervaltree_new ();
@@ -1258,6 +1284,7 @@ create_cal (ECalBackendFile *cbfile,
 {
        gchar *dirname;
        ECalBackendFilePrivate *priv;
+       icalcomponent *icalcomp;
 
        free_refresh_data (cbfile);
 
@@ -1274,7 +1301,8 @@ create_cal (ECalBackendFile *cbfile,
        g_free (dirname);
 
        /* Create the new calendar information */
-       priv->icalcomp = e_cal_util_new_top_level ();
+       icalcomp = e_cal_util_new_top_level ();
+       cal_backend_file_take_icalcomp (cbfile, icalcomp);
 
        /* Create our internal data */
        priv->comp_uid_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_object_data);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]