[dconf] begin laying async support for DConfClient



commit 38b839bf31a841c4c27a69893e476164f639187c
Author: Ryan Lortie <desrt desrt ca>
Date:   Sun May 23 18:49:29 2010 -0400

    begin laying async support for DConfClient

 client/dconf-client.c |  232 +++++++++++++++++++++++++++++++++++++++++-------
 client/dconf-client.h |    2 +
 engine/dconf-engine.c |    2 +-
 engine/dconf-engine.h |   14 ++--
 4 files changed, 208 insertions(+), 42 deletions(-)
---
diff --git a/client/dconf-client.c b/client/dconf-client.c
index 9d0088b..76025cb 100644
--- a/client/dconf-client.c
+++ b/client/dconf-client.c
@@ -1,5 +1,6 @@
 #include <dconf-engine.h>
 #include "dconf-client.h"
+#include <string.h>
 
 typedef GObjectClass DConfClientClass;
 
@@ -16,6 +17,172 @@ struct _DConfClient
 
 G_DEFINE_TYPE (DConfClient, dconf_client, G_TYPE_OBJECT)
 
+static gboolean
+dconf_client_check_reply_type (DConfEngineMessage  *dcem,
+                               GVariant            *reply,
+                               GError             **error)
+{
+  const gchar *type_string = g_variant_get_type_string (reply);
+
+  if (strcmp (type_string, dcem->reply_type) == 0)
+    return TRUE;
+
+  g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
+               "method '%s.%s' should return '%s', but we got '%s'\n",
+               dcem->interface, dcem->method, dcem->reply_type, type_string);
+  g_variant_unref (reply);
+
+  return FALSE;
+}
+
+static GBusType
+dconf_client_bus_type (DConfEngineMessage *dcem)
+{
+  switch (dcem->bus_type)
+    {
+    case 'e':
+      return G_BUS_TYPE_SESSION;
+
+    case 'y':
+      return G_BUS_TYPE_SYSTEM;
+
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+typedef struct
+{
+  GSimpleAsyncResult *simple;
+  GCancellable *cancellable;
+  DConfEngineMessage dcem;
+  GError *error;
+} DConfClientAsyncOp;
+
+static DConfClientAsyncOp *
+dconf_client_async_op_new (DConfClient         *client,
+                           gpointer             source_tag,
+                           GCancellable        *cancellable,
+                           GAsyncReadyCallback  callback,
+                           gpointer             user_data)
+{
+  DConfClientAsyncOp *op;
+
+  op = g_slice_new (DConfClientAsyncOp);
+  op->simple = g_simple_async_result_new (G_OBJECT (client), callback,
+                                          user_data, source_tag);
+  if (cancellable)
+    op->cancellable = g_object_ref (cancellable);
+  else
+    op->cancellable = NULL;
+
+  op->error = NULL;
+
+  return op;
+}
+
+static void
+dconf_client_async_op_complete (DConfClientAsyncOp *op,
+                                gboolean            in_idle)
+{
+  if (op->error != NULL)
+    {
+      g_assert (!g_simple_async_result_get_op_res_gpointer (op->simple));
+      g_simple_async_result_set_from_error (op->simple, op->error);
+      g_error_free (op->error);
+    }
+
+  else
+    g_assert (g_simple_async_result_get_op_res_gpointer (op->simple) ||
+              op->dcem.body == NULL);
+
+  if (op->cancellable)
+    g_object_unref (op->cancellable);
+
+  if (op->dcem.body)
+    g_object_unref (op->dcem.body);
+
+  if (in_idle)
+    g_simple_async_result_complete_in_idle (op->simple);
+  else
+    g_simple_async_result_complete (op->simple);
+
+  g_object_unref (op->simple);
+
+  g_slice_free (DConfClientAsyncOp, op);
+}
+
+static void
+dconf_client_async_op_call_done (GObject      *object,
+                                 GAsyncResult *result,
+                                 gpointer      user_data)
+{
+  DConfClientAsyncOp *op = user_data;
+  GVariant *reply;
+
+  reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object),
+                                         result, &op->error);
+
+  if (reply && dconf_client_check_reply_type (&op->dcem, reply, &op->error))
+      g_simple_async_result_set_op_res_gpointer (op->simple, reply,
+                                                 (GDestroyNotify) g_variant_unref);
+
+  dconf_client_async_op_complete (op, FALSE);
+}
+
+static void
+dconf_client_async_op_get_bus_done (GObject      *no_object,
+                                    GAsyncResult *result,
+                                    gpointer      user_data)
+{
+  DConfClientAsyncOp *op = user_data;
+  GDBusConnection *connection;
+
+  if ((connection = g_bus_get_finish (result, &op->error)) && op->dcem.body)
+    g_dbus_connection_call (connection,
+                            op->dcem.destination, op->dcem.object_path,
+                            op->dcem.interface, op->dcem.method,
+                            op->dcem.body, 0, -1, op->cancellable,
+                            dconf_client_async_op_call_done, op);
+
+  else
+    dconf_client_async_op_complete (op, FALSE);
+}
+
+static void
+dconf_client_async_op_run (DConfClientAsyncOp *op)
+{
+  if (op->error)
+    dconf_client_async_op_complete (op, TRUE);
+  else
+    g_bus_get (dconf_client_bus_type (&op->dcem), op->cancellable,
+               dconf_client_async_op_get_bus_done, op);
+}
+
+static gboolean
+dconf_client_async_op_finish (gpointer       client,
+                              GAsyncResult  *result,
+                              gpointer       source_tag,
+                              guint64       *sequence,
+                              GError       **error)
+{
+  GSimpleAsyncResult *simple;
+
+  g_return_val_if_fail (DCONF_IS_CLIENT (client), FALSE);
+  g_return_val_if_fail (g_simple_async_result_is_valid (result, client,
+                                                        source_tag), FALSE);
+  simple = G_SIMPLE_ASYNC_RESULT (result);
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    return FALSE;
+
+  if (sequence)
+    g_variant_get (g_simple_async_result_get_op_res_gpointer (simple),
+                   "(t)", sequence);
+
+  return TRUE;
+}
+
 static void
 dconf_client_finalize (GObject *object)
 {
@@ -67,22 +234,6 @@ dconf_client_get_connection (guint    bus_type,
 {
 }
 
-static GBusType
-dconf_client_bus_type (DConfEngineMessage *dcem)
-{
-  switch (dcem->bus_type)
-    {
-    case 'e':
-      return G_BUS_TYPE_SESSION;
-
-    case 'y':
-      return G_BUS_TYPE_SYSTEM;
-
-    default:
-      g_assert_not_reached ();
-    }
-}
-
 static gboolean
 dconf_client_call_sync (DConfClient          *client,
                         DConfEngineMessage   *dcem,
@@ -111,14 +262,8 @@ dconf_client_call_sync (DConfClient          *client,
       if (reply == NULL)
         return FALSE;
 
-      if (!g_variant_is_of_type (reply, dcem->reply_type))
-        {
-          g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
-                       "incorrect return type for '%s' method call",
-                       dcem->method);
-          g_variant_unref (reply);
-          return FALSE;
-        }
+      if (!dconf_client_check_reply_type (dcem, reply, error))
+        return FALSE;
 
       if (sequence)
         g_variant_get (reply, "(t)", sequence);
@@ -145,6 +290,35 @@ dconf_client_write (DConfClient   *client,
   return dconf_client_call_sync (client, &dcem, sequence, cancellable, error);
 }
 
+void
+dconf_client_write_async (DConfClient          *client,
+                          const gchar          *key,
+                          GVariant             *value,
+                          GCancellable         *cancellable,
+                          GAsyncReadyCallback   callback,
+                          gpointer              user_data)
+{
+  DConfClientAsyncOp *op;
+
+  op = dconf_client_async_op_new (client, dconf_client_write_async,
+                                  cancellable, callback, user_data);
+  dconf_engine_write (client->engine, &op->dcem, key, value, &op->error);
+  dconf_client_async_op_run (op);
+}
+
+gboolean
+dconf_client_write_finish (DConfClient   *client,
+                           GAsyncResult  *result,
+                           guint64       *sequence,
+                           GError       **error)
+{
+  return dconf_client_async_op_finish (client, result,
+                                       dconf_client_write_async,
+                                       sequence, error);
+}
+
+
+
 #if 0
 
 GVariant *              dconf_client_read                               (DConfClient          *client,
@@ -159,15 +333,6 @@ gboolean                dconf_client_is_writable                        (DConfCl
                                                                          const gchar          *prefix,
                                                                          GError              **error);
 
-void                    dconf_client_write_async                        (DConfClient          *client,
-                                                                         const gchar          *key,
-                                                                         GVariant             *value,
-                                                                         GAsyncReadyCallback   callback,
-                                                                         gpointer              user_data);
-gboolean                dconf_client_write_finish                       (DConfClient          *client,
-                                                                         GAsyncResult         *result,
-                                                                         GError              **error);
-
 gboolean                dconf_client_write_many                         (DConfClient          *client,
                                                                          const gchar          *prefix,
                                                                          const gchar * const  *keys,
@@ -206,4 +371,3 @@ gboolean                dconf_client_unwatch_finish                     (DConfCl
 
 #endif
 
-
diff --git a/client/dconf-client.h b/client/dconf-client.h
index 108d7a8..ed6698f 100644
--- a/client/dconf-client.h
+++ b/client/dconf-client.h
@@ -45,10 +45,12 @@ gboolean                dconf_client_write                              (DConfCl
 void                    dconf_client_write_async                        (DConfClient          *client,
                                                                          const gchar          *key,
                                                                          GVariant             *value,
+                                                                         GCancellable         *cancellable,
                                                                          GAsyncReadyCallback   callback,
                                                                          gpointer              user_data);
 gboolean                dconf_client_write_finish                       (DConfClient          *client,
                                                                          GAsyncResult         *result,
+                                                                         guint64              *sequence,
                                                                          GError              **error);
 
 gboolean                dconf_client_write_many                         (DConfClient          *client,
diff --git a/engine/dconf-engine.c b/engine/dconf-engine.c
index dbb22ed..bbc1e84 100644
--- a/engine/dconf-engine.c
+++ b/engine/dconf-engine.c
@@ -128,7 +128,7 @@ dconf_engine_dcem (DConfEngine        *engine,
   dcem->destination = "ca.desrt.dconf";
   dcem->object_path = "/";
   dcem->interface = "ca.desrt.dconf.Writer";
-  dcem->reply_type = G_VARIANT_TYPE ("(t)");
+  dcem->reply_type = "(t)";
   dcem->method = method;
 
   va_start (ap, format_string);
diff --git a/engine/dconf-engine.h b/engine/dconf-engine.h
index 9d9a77f..785fced 100644
--- a/engine/dconf-engine.h
+++ b/engine/dconf-engine.h
@@ -9,13 +9,13 @@ typedef struct _DConfEngineResetList DConfEngineResetList;
 
 typedef struct
 {
-  gint                bus_type;
-  const gchar        *destination;
-  const gchar        *object_path;
-  const gchar        *interface;
-  const gchar        *method;
-  const GVariantType *reply_type;
-  GVariant           *body;
+  gint         bus_type;
+  const gchar *destination;
+  const gchar *object_path;
+  const gchar *interface;
+  const gchar *method;
+  const gchar *reply_type;
+  GVariant    *body;
 } DConfEngineMessage;
 
 



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