diff options
author | Ryan Lortie <desrt@desrt.ca> | 2013-01-09 13:53:42 -0500 |
---|---|---|
committer | Ryan Lortie <desrt@desrt.ca> | 2013-01-09 15:29:37 -0500 |
commit | 32ad1ad75e101a83a680416e05087b415b071d8c (patch) | |
tree | 4fc8c48d368abd65b75002c692e68d6c6f3154a4 | |
parent | c15a1e3970e7c1567f6022bd85d9ab3267b08129 (diff) | |
download | dconf-32ad1ad75e101a83a680416e05087b415b071d8c.tar.gz |
service: add support for service-db
Add support for service-db to the service.
New types of service-dbs can be implemented via a GIOExtensionPoint.
-rw-r--r-- | service/dconf-service.c | 93 | ||||
-rw-r--r-- | service/dconf-writer.c | 28 | ||||
-rw-r--r-- | service/dconf-writer.h | 5 |
3 files changed, 110 insertions, 16 deletions
diff --git a/service/dconf-service.c b/service/dconf-service.c index 87eb4ca..65e7df5 100644 --- a/service/dconf-service.c +++ b/service/dconf-service.c @@ -34,9 +34,11 @@ typedef struct { GApplication parent_instance; + GIOExtensionPoint *extension_point; + DConfBlame *blame; GHashTable *writers; - guint subtree_id; + GArray *subtree_ids; } DConfService; G_DEFINE_TYPE (DConfService, dconf_service, G_TYPE_APPLICATION) @@ -90,6 +92,34 @@ string_set_add (GHashTable *set, g_hash_table_add (set, g_strdup (string)); } +static GType +dconf_service_find_writer_type (DConfService *service, + const gchar *object_path, + GHashTable **writers) +{ + GIOExtension *extension; + const gchar *path; + GHashTable *table; + + path = object_path + strlen ("/ca/desrt/dconf"); + g_assert (*path == '/'); + path++; + + extension = g_io_extension_point_get_extension_by_name (service->extension_point, path); + g_assert (extension != NULL); + + table = g_hash_table_lookup (service->writers, path); + if (table == NULL) + { + table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + g_hash_table_insert (service->writers, g_strdup (path), table); + } + + *writers = table; + + return g_io_extension_get_type (extension); +} + static gchar ** dconf_service_subtree_enumerate (GDBusConnection *connection, const gchar *sender, @@ -98,15 +128,18 @@ dconf_service_subtree_enumerate (GDBusConnection *connection, { DConfService *service = user_data; GHashTableIter iter; + GHashTable *writers; + GType writer_type; GHashTable *set; gpointer key; set = string_set_new (); - g_hash_table_iter_init (&iter, service->writers); + writer_type = dconf_service_find_writer_type (service, object_path, &writers); + g_hash_table_iter_init (&iter, writers); while (g_hash_table_iter_next (&iter, &key, NULL)) string_set_add (set, key); - dconf_writer_list (DCONF_TYPE_WRITER, set); + dconf_writer_list (writer_type, set); return string_set_free (set); } @@ -137,16 +170,20 @@ dconf_service_get_writer (DConfService *service, const gchar *name) { GDBusInterfaceSkeleton *writer; + GHashTable *writers; + GType writer_type; + + writer_type = dconf_service_find_writer_type (service, base_path, &writers); - writer = g_hash_table_lookup (service->writers, name); + writer = g_hash_table_lookup (writers, name); if (writer == NULL) { GError *error = NULL; gchar *object_path; - writer = dconf_writer_new (DCONF_TYPE_WRITER, name); - g_hash_table_insert (service->writers, g_strdup (name), writer); + writer = dconf_writer_new (writer_type, name); + g_hash_table_insert (writers, g_strdup (name), writer); object_path = g_strjoin ("/", base_path, name, NULL); g_dbus_interface_skeleton_export (writer, connection, object_path, &error); g_assert_no_error (error); @@ -188,6 +225,12 @@ dconf_service_dbus_register (GApplication *application, }; DConfService *service = DCONF_SERVICE (application); GError *local_error = NULL; + GList *node; + guint id; + + service->extension_point = g_io_extension_point_register ("dconf-backend"); + g_io_extension_point_set_required_type (service->extension_point, DCONF_TYPE_WRITER); + g_io_extension_point_implement ("dconf-backend", DCONF_TYPE_WRITER, "Writer", 0); service->blame = dconf_blame_get (); if (service->blame) @@ -197,10 +240,18 @@ dconf_service_dbus_register (GApplication *application, g_assert_no_error (local_error); } - service->subtree_id = g_dbus_connection_register_subtree (connection, "/ca/desrt/dconf/Writer", &subtree_vtable, - G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES, - g_object_ref (service), g_object_unref, &local_error); - g_assert_no_error (local_error); + for (node = g_io_extension_point_get_extensions (service->extension_point); node; node = node->next) + { + gchar *path; + + path = g_strconcat ("/ca/desrt/dconf/", g_io_extension_get_name (node->data), NULL); + g_print ("register %s\n", path); + id = g_dbus_connection_register_subtree (connection, path, &subtree_vtable, + G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES, + g_object_ref (service), g_object_unref, &local_error); + g_assert_no_error (local_error); + g_array_append_vals (service->subtree_ids, &id, 1); + } return TRUE; } @@ -211,6 +262,7 @@ dconf_service_dbus_unregister (GApplication *application, const gchar *object_path) { DConfService *service = DCONF_SERVICE (application); + gint i; if (service->blame) { @@ -219,8 +271,9 @@ dconf_service_dbus_unregister (GApplication *application, service->blame = NULL; } - g_dbus_connection_unregister_subtree (connection, service->subtree_id); - service->subtree_id = 0; + for (i = 0; i < service->subtree_ids->len; i++) + g_dbus_connection_unregister_subtree (connection, g_array_index (service->subtree_ids, guint, i)); + g_array_set_size (service->subtree_ids, 0); } static void @@ -249,11 +302,27 @@ static void dconf_service_init (DConfService *service) { service->writers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + service->subtree_ids = g_array_new (FALSE, TRUE, sizeof (guint)); +} + +static void +dconf_service_finalize (GObject *object) +{ + DConfService *service = (DConfService *) object; + + g_assert_cmpint (service->subtree_ids->len, ==, 0); + g_array_free (service->subtree_ids, TRUE); + + G_OBJECT_CLASS (dconf_service_parent_class)->finalize (object); } static void dconf_service_class_init (GApplicationClass *class) { + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = dconf_service_finalize; + class->dbus_register = dconf_service_dbus_register; class->dbus_unregister = dconf_service_dbus_unregister; class->startup = dconf_service_startup; diff --git a/service/dconf-writer.c b/service/dconf-writer.c index 26f5ecc..6df600a 100644 --- a/service/dconf-writer.c +++ b/service/dconf-writer.c @@ -38,6 +38,7 @@ struct _DConfWriterPrivate { gchar *filename; gboolean native; + gchar *basepath; gchar *name; guint64 tag; @@ -135,12 +136,24 @@ static gboolean dconf_writer_real_commit (DConfWriter *writer, GError **error) { + gint invalidate_fd = -1; + + if (!writer->priv->native) + /* If it fails, it doesn't matter... */ + invalidate_fd = open (writer->priv->filename, O_WRONLY); + if (!dconf_gvdb_utils_write_file (writer->priv->filename, writer->priv->uncommited_values, error)) return FALSE; if (writer->priv->native) dconf_shm_flag (writer->priv->name); + if (invalidate_fd != -1) + { + write (invalidate_fd, "\0\0\0\0\0\0\0\0", 8); + close (invalidate_fd); + } + if (writer->priv->commited_values) dconf_changeset_unref (writer->priv->commited_values); writer->priv->commited_values = writer->priv->uncommited_values; @@ -298,6 +311,7 @@ static void dconf_writer_init (DConfWriter *writer) { writer->priv = G_TYPE_INSTANCE_GET_PRIVATE (writer, DCONF_TYPE_WRITER, DConfWriterPrivate); + writer->priv->basepath = g_build_filename (g_get_user_config_dir (), "dconf", NULL); writer->priv->native = TRUE; } @@ -312,10 +326,7 @@ dconf_writer_set_property (GObject *object, guint prop_id, g_assert (!writer->priv->name); writer->priv->name = g_value_dup_string (value); - if (writer->priv->native) - writer->priv->filename = g_build_filename (g_get_user_config_dir (), "dconf", writer->priv->name, NULL); - else - writer->priv->filename = g_build_filename (g_get_user_runtime_dir (), "dconf", writer->priv->name, NULL); + writer->priv->filename = g_build_filename (writer->priv->basepath, writer->priv->name, NULL); } static void @@ -339,6 +350,15 @@ dconf_writer_class_init (DConfWriterClass *class) g_type_class_add_private (class, sizeof (DConfWriterPrivate)); } +void +dconf_writer_set_basepath (DConfWriter *writer, + const gchar *name) +{ + g_free (writer->priv->basepath); + writer->priv->basepath = g_build_filename (g_get_user_runtime_dir (), "dconf-service", name, NULL); + writer->priv->native = FALSE; +} + const gchar * dconf_writer_get_name (DConfWriter *writer) { diff --git a/service/dconf-writer.h b/service/dconf-writer.h index 8a2d7e4..7739ad1 100644 --- a/service/dconf-writer.h +++ b/service/dconf-writer.h @@ -68,6 +68,11 @@ struct _DConfWriter }; +GType dconf_writer_get_type (void); + +void dconf_writer_set_basepath (DConfWriter *writer, + const gchar *name); + void dconf_writer_list (GType type, GHashTable *set); GDBusInterfaceSkeleton *dconf_writer_new (GType type, |