Add e_book_client_connect_sync().
authorMatthew Barnes <mbarnes@redhat.com>
Mon, 3 Sep 2012 15:44:32 +0000 (11:44 -0400)
committerMatthew Barnes <mbarnes@redhat.com>
Wed, 30 Jan 2013 15:00:47 +0000 (10:00 -0500)
Replaces e_book_client_new() and e_client_open_sync().

e_book_client_new() is deprecated for covertly making synchronous D-Bus
calls with no way to cancel.  e_client_open_sync() is just a cumbersome
extra step now that clients are not involved in authentication.

This also adds asynchronous versions:

    e_book_client_connect()
    e_book_client_connect_finish()

addressbook/libebook/e-book-client.c
addressbook/libebook/e-book-client.h
docs/reference/addressbook/libebook/libebook-sections.txt

index c2e4130..486986b 100644 (file)
@@ -1100,6 +1100,210 @@ e_book_client_init (EBookClient *client)
 }
 
 /**
+ * e_book_client_connect_sync:
+ * @source: an #ESource
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Creates a new #EBookClient for @source.  If an error occurs, the function
+ * will set @error and return %FALSE.
+ *
+ * Unlike with e_book_client_new(), there is no need to call
+ * e_client_open_sync() after obtaining the #EBookClient.
+ *
+ * Returns: a new #EBookClient, or %NULL
+ *
+ * Since: 3.8
+ **/
+EClient *
+e_book_client_connect_sync (ESource *source,
+                            GCancellable *cancellable,
+                            GError **error)
+{
+       EBookClient *client;
+       gboolean success;
+
+       g_return_val_if_fail (E_IS_SOURCE (source), NULL);
+
+       client = g_object_new (
+               E_TYPE_BOOK_CLIENT,
+               "source", source, NULL);
+
+       success = g_initable_init (
+               G_INITABLE (client), cancellable, error);
+
+       if (success)
+               success = e_dbus_address_book_call_open_sync (
+                       client->priv->dbus_proxy, cancellable, error);
+
+       if (!success) {
+               g_object_unref (client);
+               return NULL;
+       }
+
+       return E_CLIENT (client);
+}
+
+/* Helper for e_book_client_connect() */
+static void
+book_client_connect_open_cb (GObject *source_object,
+                             GAsyncResult *result,
+                             gpointer user_data)
+{
+       GSimpleAsyncResult *simple;
+       GError *error = NULL;
+
+       simple = G_SIMPLE_ASYNC_RESULT (user_data);
+
+       e_dbus_address_book_call_open_finish (
+               E_DBUS_ADDRESS_BOOK (source_object), result, &error);
+
+       if (error != NULL)
+               g_simple_async_result_take_error (simple, error);
+
+       g_simple_async_result_complete (simple);
+
+       g_object_unref (simple);
+}
+
+/* Helper for e_book_client_connect() */
+static void
+book_client_connect_init_cb (GObject *source_object,
+                             GAsyncResult *result,
+                             gpointer user_data)
+{
+       GSimpleAsyncResult *simple;
+       GCancellable *cancellable;
+       EBookClientPrivate *priv;
+       GError *error = NULL;
+
+       simple = G_SIMPLE_ASYNC_RESULT (user_data);
+
+       g_async_initable_init_finish (
+               G_ASYNC_INITABLE (source_object), result, &error);
+
+       if (error != NULL) {
+               g_simple_async_result_take_error (simple, error);
+               g_simple_async_result_complete (simple);
+               goto exit;
+       }
+
+       /* Note, we're repurposing some function parameters. */
+
+       result = G_ASYNC_RESULT (simple);
+       source_object = g_async_result_get_source_object (result);
+       cancellable = g_simple_async_result_get_op_res_gpointer (simple);
+
+       priv = E_BOOK_CLIENT_GET_PRIVATE (source_object);
+
+       e_dbus_address_book_call_open (
+               priv->dbus_proxy, cancellable,
+               book_client_connect_open_cb,
+               g_object_ref (simple));
+
+       g_object_unref (source_object);
+
+exit:
+       g_object_unref (simple);
+}
+
+/**
+ * e_book_client_connect:
+ * @source: an #ESource
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @callback: (scope async): a #GAsyncReadyCallback to call when the request
+ *            is satisfied
+ * @user_data: (closure): data to pass to the callback function
+ *
+ * Asynchronously creates a new #EBookClient for @source.
+ *
+ * Unlike with e_book_client_new(), there is no need to call e_client_open()
+ * after obtaining the #EBookClient.
+ *
+ * When the operation is finished, @callback will be called.  You can then
+ * call e_book_client_connect_finish() to get the result of the operation.
+ *
+ * Since: 3.8
+ **/
+void
+e_book_client_connect (ESource *source,
+                       GCancellable *cancellable,
+                       GAsyncReadyCallback callback,
+                       gpointer user_data)
+{
+       GSimpleAsyncResult *simple;
+       EBookClient *client;
+
+       g_return_if_fail (E_IS_SOURCE (source));
+
+       /* Two things with this: 1) instantiate the client object
+        * immediately to make sure the thread-default GMainContext
+        * gets plucked, and 2) do not call the D-Bus open() method
+        * from our designated D-Bus thread -- it may take a long
+        * time and block other clients from receiving signals. */
+
+       client = g_object_new (
+               E_TYPE_BOOK_CLIENT,
+               "source", source, NULL);
+
+       simple = g_simple_async_result_new (
+               G_OBJECT (client), callback,
+               user_data, e_book_client_connect);
+
+       g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+       if (G_IS_CANCELLABLE (cancellable)) {
+               /* XXX Stuff the GCancellable in the GSimpleAsyncResult
+                *     so we don't have to carry an AsyncContext struct. */
+               g_simple_async_result_set_op_res_gpointer (
+                       simple, g_object_ref (cancellable),
+                       (GDestroyNotify) g_object_unref);
+       }
+
+       g_async_initable_init_async (
+               G_ASYNC_INITABLE (client),
+               G_PRIORITY_DEFAULT, cancellable,
+               book_client_connect_init_cb,
+               g_object_ref (simple));
+
+       g_object_unref (simple);
+       g_object_unref (client);
+}
+
+/**
+ * e_book_client_connect_finish:
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with e_book_client_connect().  If an
+ * error occurs in connecting to the D-Bus service, the function sets
+ * @error and returns %NULL.
+ *
+ * Returns: a new #EBookClient, or %NULL
+ *
+ * Since: 3.8
+ **/
+EClient *
+e_book_client_connect_finish (GAsyncResult *result,
+                              GError **error)
+{
+       GSimpleAsyncResult *simple;
+       gpointer source_tag;
+
+       g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
+
+       simple = G_SIMPLE_ASYNC_RESULT (result);
+
+       source_tag = g_simple_async_result_get_source_tag (simple);
+       g_return_val_if_fail (source_tag == e_book_client_connect, NULL);
+
+       if (g_simple_async_result_propagate_error (simple, error))
+               return NULL;
+
+       return E_CLIENT (g_async_result_get_source_object (result));
+}
+
+/**
  * e_book_client_new:
  * @source: An #ESource pointer
  * @error: A #GError pointer
@@ -1111,6 +1315,11 @@ e_book_client_init (EBookClient *client)
  * Returns: a new but unopened #EBookClient.
  *
  * Since: 3.2
+ *
+ * Deprecated: 3.8: It covertly makes synchronous D-Bus calls, with no
+ *                  way to cancel.  Use e_book_client_connect() instead,
+ *                  which combines e_book_client_new() and e_client_open()
+ *                  into one step.
  **/
 EBookClient *
 e_book_client_new (ESource *source,
index 1e782ab..19334fc 100644 (file)
@@ -121,7 +121,14 @@ GError *   e_book_client_error_create      (EBookClientError code,
                                                 const gchar *custom_msg);
 
 GType          e_book_client_get_type          (void) G_GNUC_CONST;
-EBookClient *  e_book_client_new               (ESource *source,
+EClient *      e_book_client_connect_sync      (ESource *source,
+                                                GCancellable *cancellable,
+                                                GError **error);
+void           e_book_client_connect           (ESource *source,
+                                                GCancellable *cancellable,
+                                                GAsyncReadyCallback callback,
+                                                gpointer user_data);
+EClient *      e_book_client_connect_finish    (GAsyncResult *result,
                                                 GError **error);
 gboolean       e_book_client_get_self          (ESourceRegistry *registry,
                                                 EContact **out_contact,
@@ -302,7 +309,10 @@ gboolean   e_book_client_get_view_sync     (EBookClient *client,
  * Deprecated: 3.8: The property is no longer supported.
  **/
 #define BOOK_BACKEND_PROPERTY_SUPPORTED_AUTH_METHODS   "supported-auth-methods"
-#endif /* EDS_DISABLE_DEPRECATED */
+
+EBookClient *  e_book_client_new               (ESource *source,
+                                                GError **error);
+#endif /* E_BOOK_DISABLE_DEPRECATED */
 
 G_END_DECLS
 
index 75d842e..1c5a497 100644 (file)
@@ -118,7 +118,9 @@ EBookClientError
 e_book_client_error_to_string
 e_book_client_error_create
 EBookClient
-e_book_client_new
+e_book_client_connect_sync
+e_book_client_connect
+e_book_client_connect_finish
 e_book_client_get_self
 e_book_client_set_self
 e_book_client_is_self
@@ -157,6 +159,7 @@ e_book_client_get_view_finish
 e_book_client_get_view_sync
 <SUBSECTION Deprecated>
 BOOK_BACKEND_PROPERTY_SUPPORTED_AUTH_METHODS
+e_book_client_new
 <SUBSECTION Standard>
 E_BOOK_CLIENT
 E_IS_BOOK_CLIENT