[evolution-data-server] ECalBackendStore: Better ensure final save works.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] ECalBackendStore: Better ensure final save works.
- Date: Wed, 9 Jan 2013 20:13:57 +0000 (UTC)
commit 2707aa92740bb6510b6dab4a511f6bfe45adfa4f
Author: Matthew Barnes <mbarnes redhat com>
Date: Wed Jan 9 14:12:53 2013 -0500
ECalBackendStore: Better ensure final save works.
Collect what we need from ETimezoneCache when we schedule the save
instead of relying on ETimezoneCache when we actually do the save.
calendar/libedata-cal/e-cal-backend-store.c | 80 +++++++++++++++++++++------
1 files changed, 62 insertions(+), 18 deletions(-)
---
diff --git a/calendar/libedata-cal/e-cal-backend-store.c b/calendar/libedata-cal/e-cal-backend-store.c
index cd41f2b..1fa1120 100644
--- a/calendar/libedata-cal/e-cal-backend-store.c
+++ b/calendar/libedata-cal/e-cal-backend-store.c
@@ -62,6 +62,7 @@ struct _ECalBackendStorePrivate {
guint save_timeout_id;
GMutex save_timeout_lock;
+ GList *timezones_to_save;
};
enum {
@@ -102,6 +103,12 @@ destroy_full_object (FullCompObject *obj)
}
static void
+cal_backend_store_free_zone (icaltimezone *zone)
+{
+ icaltimezone_free (zone, 1);
+}
+
+static void
cal_backend_store_add_timezone (ECalBackendStore *store,
icalcomponent *vtzcomp)
{
@@ -280,39 +287,32 @@ cal_backend_store_scan_vcalendar (ECalBackendStore *store,
}
static void
-cal_backend_store_save_cache_now (ECalBackendStore *store)
+cal_backend_store_save_cache_now (ECalBackendStore *store,
+ GList *timezones_to_save)
{
- ETimezoneCache *timezone_cache;
GHashTableIter iter;
- GList *list, *link;
icalcomponent *vcalcomp;
gchar *data = NULL, *tmpfile;
gsize len, nwrote;
gpointer value;
FILE *f;
- /* Since we only hold a weak reference on the ETimezoneCache,
- * make sure we still have it before proceeding. If we lost
- * the ETimezoneCache, abort the save with a console warning
- * to avoid wiping out saved time zone data. */
- timezone_cache = e_cal_backend_store_ref_timezone_cache (store);
- g_return_if_fail (timezone_cache != NULL);
-
g_rw_lock_reader_lock (&store->priv->lock);
vcalcomp = e_cal_util_new_top_level ();
/* Add all timezone components. */
- list = e_timezone_cache_list_timezones (timezone_cache);
- for (link = list; link != NULL; link = g_list_next (link)) {
- icaltimezone *tz = link->data;
+ while (timezones_to_save != NULL) {
+ icaltimezone *tz;
icalcomponent *tzcomp;
+ tz = timezones_to_save->data;
tzcomp = icaltimezone_get_component (tz);
tzcomp = icalcomponent_new_clone (tzcomp);
icalcomponent_add_component (vcalcomp, tzcomp);
+
+ timezones_to_save = g_list_next (timezones_to_save);
}
- g_list_free (list);
/* Add all non-timezone components. */
g_hash_table_iter_init (&iter, store->priv->comp_uid_hash);
@@ -358,7 +358,6 @@ cal_backend_store_save_cache_now (ECalBackendStore *store)
error:
g_rw_lock_reader_unlock (&store->priv->lock);
- g_object_unref (timezone_cache);
g_free (tmpfile);
g_free (data);
}
@@ -367,14 +366,21 @@ static gboolean
cal_backend_store_save_cache_timeout_cb (gpointer user_data)
{
ECalBackendStore *store;
+ GList *timezones_to_save;
store = E_CAL_BACKEND_STORE (user_data);
g_mutex_lock (&store->priv->save_timeout_lock);
store->priv->save_timeout_id = 0;
+ timezones_to_save = store->priv->timezones_to_save;
+ store->priv->timezones_to_save = NULL;
g_mutex_unlock (&store->priv->save_timeout_lock);
- cal_backend_store_save_cache_now (store);
+ cal_backend_store_save_cache_now (store, timezones_to_save);
+
+ g_list_free_full (
+ timezones_to_save,
+ (GDestroyNotify) cal_backend_store_free_zone);
return FALSE;
}
@@ -382,6 +388,29 @@ cal_backend_store_save_cache_timeout_cb (gpointer user_data)
static void
cal_backend_store_save_cache (ECalBackendStore *store)
{
+ ETimezoneCache *timezone_cache;
+ GList *list, *link;
+
+ timezone_cache = e_cal_backend_store_ref_timezone_cache (store);
+ g_return_if_fail (timezone_cache != NULL);
+
+ /* Clone the icaltimezone structs in case
+ * the timeout outlives the ETimezoneCache. */
+ list = e_timezone_cache_list_timezones (timezone_cache);
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ icaltimezone *tz;
+ icalcomponent *tzcomp;
+
+ tz = icaltimezone_new ();
+ tzcomp = icaltimezone_get_component (link->data);
+ tzcomp = icalcomponent_new_clone (tzcomp);
+ icaltimezone_set_component (tz, tzcomp);
+
+ link->data = tz;
+ }
+
+ g_object_unref (timezone_cache);
+
g_mutex_lock (&store->priv->save_timeout_lock);
if (store->priv->save_timeout_id > 0)
@@ -391,6 +420,12 @@ cal_backend_store_save_cache (ECalBackendStore *store)
IDLE_SAVE_TIMEOUT_SECONDS,
cal_backend_store_save_cache_timeout_cb, store);
+ g_list_free_full (
+ store->priv->timezones_to_save,
+ (GDestroyNotify) cal_backend_store_free_zone);
+
+ store->priv->timezones_to_save = list; /* takes ownership */
+
g_mutex_unlock (&store->priv->save_timeout_lock);
}
@@ -477,6 +512,7 @@ cal_backend_store_dispose (GObject *object)
{
ECalBackendStorePrivate *priv;
ETimezoneCache *timezone_cache;
+ GList *timezones_to_save = NULL;
gboolean save_needed = FALSE;
priv = E_CAL_BACKEND_STORE_GET_PRIVATE (object);
@@ -486,12 +522,20 @@ cal_backend_store_dispose (GObject *object)
if (priv->save_timeout_id > 0) {
g_source_remove (priv->save_timeout_id);
priv->save_timeout_id = 0;
+ timezones_to_save = priv->timezones_to_save;
+ priv->timezones_to_save = NULL;
save_needed = TRUE;
}
g_mutex_unlock (&priv->save_timeout_lock);
- if (save_needed)
+
+ if (save_needed) {
cal_backend_store_save_cache_now (
- E_CAL_BACKEND_STORE (object));
+ E_CAL_BACKEND_STORE (object),
+ timezones_to_save);
+ g_list_free_full (
+ timezones_to_save,
+ (GDestroyNotify) cal_backend_store_free_zone);
+ }
timezone_cache = g_weak_ref_get (&priv->timezone_cache);
if (timezone_cache != NULL) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]