diff options
author | Milan Crha <mcrha@redhat.com> | 2015-11-19 08:21:00 +0100 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2015-11-19 08:21:50 +0100 |
commit | 25ea5b2fcfd240a5d70973be4fd27b65fbe86bd0 (patch) | |
tree | b6a153dcf1eea5ace15a0eb244f6eca2668a0f82 | |
parent | f071e7a326485926323a85c3ed6b48b86437fb3a (diff) | |
download | evolution-data-server-25ea5b2fcfd240a5d70973be4fd27b65fbe86bd0.tar.gz |
Bug 702127 - Crash under cal_backend_store_save_cache_now()
-rw-r--r-- | calendar/libedata-cal/e-cal-backend-store.c | 57 |
1 files changed, 53 insertions, 4 deletions
diff --git a/calendar/libedata-cal/e-cal-backend-store.c b/calendar/libedata-cal/e-cal-backend-store.c index 3fbce5fb7..acde6d76d 100644 --- a/calendar/libedata-cal/e-cal-backend-store.c +++ b/calendar/libedata-cal/e-cal-backend-store.c @@ -363,21 +363,60 @@ cal_backend_store_save_cache_now (ECalBackendStore *store, if (g_rename (tmpfile, store->priv->cache_file_name) != 0) g_unlink (tmpfile); + store->priv->dirty = FALSE; + error: g_rw_lock_reader_unlock (&store->priv->lock); g_free (tmpfile); g_free (data); } +static void +cal_backend_store_toggle_ref_cb (gpointer data, + GObject *object, + gboolean is_last_ref) +{ + ECalBackendStore *store; + + g_return_if_fail (E_IS_CAL_BACKEND_STORE (object)); + + if (!is_last_ref) + return; + + store = E_CAL_BACKEND_STORE (object); + + g_mutex_lock (&store->priv->save_timeout_lock); + g_object_ref (store); + g_object_remove_toggle_ref (G_OBJECT (store), cal_backend_store_toggle_ref_cb, NULL); + store->priv->dirty = TRUE; + store->priv->save_timeout_id = 0; + g_mutex_unlock (&store->priv->save_timeout_lock); + + g_object_unref (store); +} + static gboolean cal_backend_store_save_cache_timeout_cb (gpointer user_data) { ECalBackendStore *store; + GSource *source; GList *timezones_to_save; + source = g_main_current_source (); + if (g_source_is_destroyed (source)) + return FALSE; + store = E_CAL_BACKEND_STORE (user_data); g_mutex_lock (&store->priv->save_timeout_lock); + if (store->priv->save_timeout_id != g_source_get_id (source)) { + g_mutex_unlock (&store->priv->save_timeout_lock); + return FALSE; + } + + g_object_ref (store); + + g_object_remove_toggle_ref (G_OBJECT (store), cal_backend_store_toggle_ref_cb, NULL); store->priv->save_timeout_id = 0; timezones_to_save = store->priv->timezones_to_save; store->priv->timezones_to_save = NULL; @@ -389,6 +428,8 @@ cal_backend_store_save_cache_timeout_cb (gpointer user_data) timezones_to_save, (GDestroyNotify) cal_backend_store_free_zone); + g_object_unref (store); + return FALSE; } @@ -420,8 +461,12 @@ cal_backend_store_save_cache (ECalBackendStore *store) g_mutex_lock (&store->priv->save_timeout_lock); - if (store->priv->save_timeout_id > 0) + if (store->priv->save_timeout_id > 0) { g_source_remove (store->priv->save_timeout_id); + g_object_remove_toggle_ref (G_OBJECT (store), cal_backend_store_toggle_ref_cb, NULL); + } + + g_object_add_toggle_ref (G_OBJECT (store), cal_backend_store_toggle_ref_cb, NULL); store->priv->save_timeout_id = e_named_timeout_add_seconds ( IDLE_SAVE_TIMEOUT_SECONDS, @@ -526,9 +571,13 @@ cal_backend_store_dispose (GObject *object) /* If a save is scheduled, cancel it and save now. */ g_mutex_lock (&priv->save_timeout_lock); - if (priv->save_timeout_id > 0) { - g_source_remove (priv->save_timeout_id); - priv->save_timeout_id = 0; + if (priv->save_timeout_id > 0 || priv->dirty) { + if (priv->save_timeout_id > 0) { + g_object_remove_toggle_ref (object, cal_backend_store_toggle_ref_cb, NULL); + 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; |