summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorRyan Lortie <desrt@desrt.ca>2013-01-09 13:53:42 -0500
committerRyan Lortie <desrt@desrt.ca>2013-01-09 15:29:37 -0500
commit32ad1ad75e101a83a680416e05087b415b071d8c (patch)
tree4fc8c48d368abd65b75002c692e68d6c6f3154a4 /service
parentc15a1e3970e7c1567f6022bd85d9ab3267b08129 (diff)
downloaddconf-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.
Diffstat (limited to 'service')
-rw-r--r--service/dconf-service.c93
-rw-r--r--service/dconf-writer.c28
-rw-r--r--service/dconf-writer.h5
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,