summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Untz <vuntz@gnome.org>2011-10-17 19:58:20 +0200
committerRoss Burton <ross@linux.intel.com>2011-10-23 21:08:35 +0100
commitd77bfc60f0e27d1db24a18661f1a248307307ce1 (patch)
tree88c7eeb2b7f37c74fcce30f6fe5db391f755f230
parentd7635af672cd3d4929498f30a93263aa77fa7403 (diff)
downloadgconf-d77bfc60f0e27d1db24a18661f1a248307307ce1.tar.gz
gconf-dbus: On SIGHUP, do not recreate databases but reload the sources
When we destroy and recreate a database, the object path associated to it on dbus changes. This is bad as clients do not know about the object path change, and therefore fail. Instead of destroying and recreating the databases, we simply reload the sources for this database. This achieves the same result, without changing the object path. Note that for the corba backend, we still use the old way as simply reloading the sources might not work -- the sources are used in corba-specific code. https://bugzilla.gnome.org/show_bug.cgi?id=659835
-rw-r--r--gconf/gconf-database.c29
-rw-r--r--gconf/gconf-database.h3
-rw-r--r--gconf/gconfd.c80
3 files changed, 98 insertions, 14 deletions
diff --git a/gconf/gconf-database.c b/gconf/gconf-database.c
index 81c1b0e2..63dfc085 100644
--- a/gconf/gconf-database.c
+++ b/gconf/gconf-database.c
@@ -791,6 +791,29 @@ static void source_notify_cb (GConfSource *source,
const gchar *location,
GConfDatabase *db);
+void
+gconf_database_set_sources (GConfDatabase *db,
+ GConfSources *sources)
+{
+ if (db->sources != NULL)
+ {
+#ifdef HAVE_CORBA
+ /* this function should only be used when creating the db with the corba
+ * backend */
+ g_assert_not_reached ();
+#endif
+
+ gconf_sources_clear_cache(db->sources);
+ gconf_sources_free(db->sources);
+ }
+
+ db->sources = sources;
+
+ gconf_sources_set_notify_func (db->sources,
+ (GConfSourceNotifyFunc) source_notify_cb,
+ db);
+}
+
GConfDatabase*
gconf_database_new (GConfSources *sources)
{
@@ -827,11 +850,7 @@ gconf_database_new (GConfSources *sources)
db->listeners = gconf_listeners_new();
- db->sources = sources;
-
- gconf_sources_set_notify_func (db->sources,
- (GConfSourceNotifyFunc) source_notify_cb,
- db);
+ gconf_database_set_sources(db, sources);
db->last_access = time(NULL);
diff --git a/gconf/gconf-database.h b/gconf/gconf-database.h
index 2d91fdc1..07ae3ce4 100644
--- a/gconf/gconf-database.h
+++ b/gconf/gconf-database.h
@@ -71,6 +71,9 @@ struct _GConfDatabase
GConfDatabase* gconf_database_new (GConfSources *sources);
void gconf_database_free (GConfDatabase *db);
+void gconf_database_set_sources (GConfDatabase *db,
+ GConfSources *sources);
+
void gconf_database_drop_dead_listeners (GConfDatabase *db);
#ifdef HAVE_CORBA
diff --git a/gconf/gconfd.c b/gconf/gconfd.c
index 0b06b64e..33deb48d 100644
--- a/gconf/gconfd.c
+++ b/gconf/gconfd.c
@@ -149,6 +149,9 @@ static void enter_shutdown (void);
static void init_databases (void);
static void shutdown_databases (void);
+#ifdef HAVE_DBUS
+static void reload_databases (void);
+#endif
static void set_default_database (GConfDatabase* db);
static void register_database (GConfDatabase* db);
static void unregister_database (GConfDatabase* db);
@@ -353,8 +356,8 @@ gconfd_shutdown(PortableServer_Servant servant, CORBA_Environment *ev)
/* This needs to be called before we register with OAF
*/
-static void
-gconf_server_load_sources(void)
+static GConfSources *
+gconf_server_get_default_sources(void)
{
GSList* addresses;
GList* tmp;
@@ -406,8 +409,7 @@ gconf_server_load_sources(void)
/* don't request error since there aren't any addresses */
sources = gconf_sources_new_from_addresses(NULL, NULL);
- /* Install the sources as the default database */
- set_default_database (gconf_database_new(sources));
+ return sources;
}
else
{
@@ -446,12 +448,21 @@ gconf_server_load_sources(void)
if (!have_writable)
gconf_log(GCL_WARNING, _("No writable configuration sources successfully resolved. May be unable to save some configuration changes"));
-
- /* Install the sources as the default database */
- set_default_database (gconf_database_new(sources));
+ return sources;
}
}
+static void
+gconf_server_load_sources(void)
+{
+ GConfSources* sources;
+
+ sources = gconf_server_get_default_sources();
+
+ /* Install the sources as the default database */
+ set_default_database (gconf_database_new(sources));
+}
+
/*
* Signal handlers should not log debug messages as this code is non-reentrant.
* Please avoid calling gconf_log in this function.
@@ -1030,13 +1041,14 @@ periodic_cleanup_timeout(gpointer data)
need_db_reload = FALSE;
#ifdef HAVE_CORBA
logfile_save ();
-#endif
shutdown_databases ();
init_databases ();
gconf_server_load_sources ();
-#ifdef HAVE_CORBA
logfile_read ();
#endif
+#ifdef HAVE_DBUS
+ reload_databases ();
+#endif
}
gconf_log (GCL_DEBUG, "Performing periodic cleanup, expiring cache cruft");
@@ -1319,6 +1331,56 @@ shutdown_databases (void)
default_db = NULL;
}
+#ifdef HAVE_DBUS
+static void
+reload_databases (void)
+{
+ GConfSources* sources;
+ GList *tmp_list;
+
+ sources = gconf_server_get_default_sources ();
+ gconf_database_set_sources (default_db, sources);
+
+ tmp_list = db_list;
+ while (tmp_list)
+ {
+ GConfDatabase* db = tmp_list->data;
+ GList *l;
+ GConfSource *source;
+ GSList *addresses = NULL;
+ GError *error = NULL;
+
+ if (db == default_db)
+ {
+ tmp_list = g_list_next (tmp_list);
+ continue;
+ }
+
+ for (l = db->sources->sources; l != NULL; l = l->next)
+ {
+ source = l->data;
+ addresses = g_slist_prepend (addresses, source->address);
+ }
+
+ addresses = g_slist_reverse (addresses);
+ sources = gconf_sources_new_from_addresses (addresses, &error);
+
+ if (error == NULL)
+ {
+ gconf_database_set_sources (db, sources);
+ }
+ else
+ {
+ /* if we got an error, keep our old sources -- that's better than
+ * nothing */
+ g_error_free (error);
+ }
+
+ tmp_list = g_list_next (tmp_list);
+ }
+}
+#endif
+
static gboolean
no_databases_in_use (void)
{