[gconf] gconf-dbus: On SIGHUP, do not recreate databases but reload the sources



commit d77bfc60f0e27d1db24a18661f1a248307307ce1
Author: Vincent Untz <vuntz gnome org>
Date:   Mon Oct 17 19:58:20 2011 +0200

    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

 gconf/gconf-database.c |   29 ++++++++++++++---
 gconf/gconf-database.h |    3 ++
 gconf/gconfd.c         |   80 ++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 98 insertions(+), 14 deletions(-)
---
diff --git a/gconf/gconf-database.c b/gconf/gconf-database.c
index 81c1b0e..63dfc08 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 2d91fdc..07ae3ce 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 0b06b64..33deb48 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)
 {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]