diff options
author | Ryan Lortie <desrt@desrt.ca> | 2011-01-14 11:09:31 -0500 |
---|---|---|
committer | Ryan Lortie <desrt@desrt.ca> | 2011-01-14 11:09:31 -0500 |
commit | 0e48388eb0d97d72c9914fe724e3a23b28d5e82c (patch) | |
tree | 8f3a42bfc21cf874b740994d84a6f6c90d0184d5 /gsettings | |
parent | dfcb5dc47e0dcd8b8384f34b6368826fa0851694 (diff) | |
download | dconf-0e48388eb0d97d72c9914fe724e3a23b28d5e82c.tar.gz |
Bug 639523 - crash when DCONF_PROFILE is set
When using multiple databases in a single profile, dconf uses some freed
memory (due to the AddMatch asynchronous callback being called multiple
times and freeing the memory each time).
Fix that with a reference count.
Diffstat (limited to 'gsettings')
-rw-r--r-- | gsettings/dconfsettingsbackend.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/gsettings/dconfsettingsbackend.c b/gsettings/dconfsettingsbackend.c index ad42574..0cab0d3 100644 --- a/gsettings/dconfsettingsbackend.c +++ b/gsettings/dconfsettingsbackend.c @@ -479,6 +479,7 @@ typedef struct DConfSettingsBackend *dcsb; guint64 state; gchar name[1]; + gint outstanding; } OutstandingWatch; static OutstandingWatch * @@ -492,6 +493,7 @@ outstanding_watch_new (DConfSettingsBackend *dcsb, watch = g_malloc (G_STRUCT_OFFSET (OutstandingWatch, name) + length + 1); watch->dcsb = g_object_ref (dcsb); watch->state = dconf_engine_get_state (dcsb->engine); + watch->outstanding = 0; strcpy (watch->name, name); return watch; @@ -500,8 +502,11 @@ outstanding_watch_new (DConfSettingsBackend *dcsb, static void outstanding_watch_free (OutstandingWatch *watch) { - g_object_unref (watch->dcsb); - g_free (watch); + if (--watch->outstanding == 0) + { + g_object_unref (watch->dcsb); + g_free (watch); + } } static void @@ -550,6 +555,8 @@ dconf_settings_backend_subscribe_context_func (gpointer data) DConfEngineMessage dcem; dconf_engine_watch (watch->dcsb->engine, watch->name, &dcem); + watch->outstanding = dcem.n_messages; + dconf_settings_backend_send (watch->dcsb, &dcem, add_match_done, watch); dconf_engine_message_destroy (&dcem); |