aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2010-05-20 05:48:58 +0800
committerMilan Crha <mcrha@redhat.com>2010-05-20 05:48:58 +0800
commit7aa52ff5caaaa6044be90b04af375d6c63e38355 (patch)
treec0aa5372ebfcabe8952d48956c3d4c28929713e6
parent98adb40685d4a454d792b23c6ba23468b95c6216 (diff)
downloadgsoc2013-evolution-7aa52ff5caaaa6044be90b04af375d6c63e38355.tar.gz
gsoc2013-evolution-7aa52ff5caaaa6044be90b04af375d6c63e38355.tar.zst
gsoc2013-evolution-7aa52ff5caaaa6044be90b04af375d6c63e38355.zip
Bug #220672 - Excessive autosaving uses lots of resources
-rw-r--r--composer/e-composer-autosave.c78
1 files changed, 53 insertions, 25 deletions
diff --git a/composer/e-composer-autosave.c b/composer/e-composer-autosave.c
index a850cf9b77..3db7ef20e4 100644
--- a/composer/e-composer-autosave.c
+++ b/composer/e-composer-autosave.c
@@ -32,13 +32,17 @@
typedef struct _AutosaveState AutosaveState;
struct _AutosaveState {
+ EMsgComposer *composer;
GFile *file;
+ gboolean changed;
+ guint source_id; /* timeout source ID */
gboolean enabled;
gboolean error_shown;
};
static GList *autosave_registry;
-static guint autosave_source_id;
+
+static void composer_changed_cb (EMsgComposer *composer);
static EMsgComposer *
composer_autosave_registry_lookup (const gchar *basename)
@@ -67,12 +71,17 @@ composer_autosave_registry_lookup (const gchar *basename)
}
static AutosaveState *
-composer_autosave_state_new (void)
+composer_autosave_state_new (EMsgComposer *composer)
{
AutosaveState *state;
state = g_slice_new0 (AutosaveState);
state->enabled = TRUE;
+ state->changed = FALSE;
+ state->source_id = 0;
+ state->composer = composer;
+
+ g_signal_connect (composer, "notify::changed", G_CALLBACK (composer_changed_cb), NULL);
return state;
}
@@ -80,6 +89,8 @@ composer_autosave_state_new (void)
static void
composer_autosave_state_free (AutosaveState *state)
{
+ if (state->source_id)
+ g_source_remove (state->source_id);
if (state->file)
g_object_unref (state->file);
g_slice_free (AutosaveState, state);
@@ -153,26 +164,54 @@ composer_autosave_finish_cb (EMsgComposer *composer,
}
}
-static void
-composer_autosave_foreach (EMsgComposer *composer)
+static gboolean
+composer_autosave_timeout (EMsgComposer *composer)
{
- /* Make sure the composer is still alive. */
- g_return_if_fail (E_IS_MSG_COMPOSER (composer));
+ AutosaveState *state;
+
+ g_return_val_if_fail (composer != NULL, FALSE);
+ g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);
- if (e_composer_autosave_get_enabled (composer))
+ state = g_object_get_data (G_OBJECT (composer), "autosave");
+ g_return_val_if_fail (state != NULL, FALSE);
+ g_return_val_if_fail (state->composer == composer, FALSE);
+
+ if (!state->changed) {
+ state->source_id = 0;
+ return FALSE;
+ }
+
+ composer = state->composer;
+
+ if (e_composer_autosave_get_enabled (composer)) {
+ state->changed = FALSE;
e_composer_autosave_snapshot_async (
composer, (GAsyncReadyCallback)
composer_autosave_finish_cb, NULL);
+ }
+
+ return TRUE;
}
-static gboolean
-composer_autosave_timeout (void)
+static void
+composer_changed_cb (EMsgComposer *composer)
{
- g_list_foreach (
- autosave_registry, (GFunc)
- composer_autosave_foreach, NULL);
+ AutosaveState *state;
- return TRUE;
+ g_return_if_fail (composer != NULL);
+ g_return_if_fail (E_IS_MSG_COMPOSER (composer));
+
+ state = g_object_get_data (G_OBJECT (composer), "autosave");
+ g_return_if_fail (state != NULL);
+ g_return_if_fail (state->composer == composer);
+
+ g_object_get (G_OBJECT (composer), "changed", &state->changed, NULL);
+
+ if (state->changed && state->source_id == 0) {
+ state->source_id = g_timeout_add_seconds (
+ AUTOSAVE_INTERVAL, (GSourceFunc)
+ composer_autosave_timeout, state->composer);
+ }
}
static void
@@ -182,12 +221,6 @@ composer_autosave_notify (gpointer unused,
/* Remove the dead composer from the registry. */
autosave_registry = g_list_remove (
autosave_registry, where_the_object_was);
-
- /* Cancel timeouts if the registry is now empty. */
- if (autosave_registry == NULL && autosave_source_id != 0) {
- g_source_remove (autosave_source_id);
- autosave_source_id = 0;
- }
}
GList *
@@ -256,7 +289,7 @@ e_composer_autosave_register (EMsgComposer *composer)
g_object_set_data_full (
G_OBJECT (composer), "autosave",
- composer_autosave_state_new (),
+ composer_autosave_state_new (composer),
(GDestroyNotify) composer_autosave_state_free);
autosave_registry = g_list_prepend (autosave_registry, composer);
@@ -264,11 +297,6 @@ e_composer_autosave_register (EMsgComposer *composer)
g_object_weak_ref (
G_OBJECT (composer), (GWeakNotify)
composer_autosave_notify, NULL);
-
- if (autosave_source_id == 0)
- autosave_source_id = g_timeout_add_seconds (
- AUTOSAVE_INTERVAL, (GSourceFunc)
- composer_autosave_timeout, NULL);
}
void