GDBusConnection: Fix up g_dbus_connection_close()
authorDavid Zeuthen <davidz@redhat.com>
Wed, 14 Jul 2010 16:37:32 +0000 (12:37 -0400)
committerDavid Zeuthen <davidz@redhat.com>
Wed, 14 Jul 2010 16:37:32 +0000 (12:37 -0400)
... so it is async, cancelable and returns an error. Also provide a
synchronous version.

This is an API/ABI break but it is expected that only very few
applications use this API.

Signed-off-by: David Zeuthen <davidz@redhat.com>
docs/reference/gio/gio-sections.txt
gio/gdbusconnection.c
gio/gdbusconnection.h
gio/gio.symbols
gio/tests/gdbus-connection.c

index efbaf90118e4c0ff082f64cfe73f2b310bf4d5b2..e0d5b8cc9e6e5449a882e2f5acd4a81485fb81f1 100644 (file)
@@ -2360,6 +2360,8 @@ g_dbus_connection_new_for_address_finish
 g_dbus_connection_new_for_address_sync
 g_dbus_connection_start_message_processing
 g_dbus_connection_close
+g_dbus_connection_close_finish
+g_dbus_connection_close_sync
 g_dbus_connection_is_closed
 g_dbus_connection_flush
 g_dbus_connection_flush_finish
index 80f1fe4d7a26b96c2771ff01348f81cab68474ce..7290e2005c9980c86ef8606b787dc385b4084e65 100644 (file)
@@ -1036,6 +1036,7 @@ g_dbus_connection_flush_sync (GDBusConnection  *connection,
   gboolean ret;
 
   g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
   ret = FALSE;
 
@@ -1122,46 +1123,162 @@ set_closed_unlocked (GDBusConnection *connection,
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+static void
+close_in_thread_func (GSimpleAsyncResult *res,
+                      GObject            *object,
+                      GCancellable       *cancellable)
+{
+  GError *error;
+
+  error = NULL;
+  if (!g_dbus_connection_close_sync (G_DBUS_CONNECTION (object),
+                                     cancellable,
+                                     &error))
+    {
+      g_simple_async_result_set_from_error (res, error);
+      g_error_free (error);
+    }
+}
+
 /**
  * g_dbus_connection_close:
  * @connection: A #GDBusConnection.
+ * @cancellable: A #GCancellable or %NULL.
+ * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL if you don't
+ * care about the result.
+ * @user_data: The data to pass to @callback.
  *
  * Closes @connection. Note that this never causes the process to
  * exit (this might only happen if the other end of a shared message
  * bus connection disconnects, see #GDBusConnection:exit-on-close).
  *
- * Once the stream is closed, all operations will return
+ * Once the connection is closed, operations such as sending a message
+ * will return with the error %G_IO_ERROR_CLOSED. Closing a connection
+ * will not automatically flush the connection so queued messages may
+ * be lost. Use g_dbus_connection_flush() if you need such guarantees.
+ *
+ * If @connection is already closed, this method fails with
  * %G_IO_ERROR_CLOSED.
  *
- * Note that closing a connection will not automatically flush the
- * connection so queued messages may be lost. Use
- * g_dbus_connection_flush() if you need such guarantees.
+ * When @connection has been closed, the #GDBusConnection::closed
+ * signal is emitted in the <link
+ * linkend="g-main-context-push-thread-default">thread-default main
+ * loop</link> of the thread that @connection was constructed in.
  *
- * If @connection is already closed, this method does nothing.
+ * This is an asynchronous method. When the operation is finished,
+ * @callback will be invoked in the <link
+ * linkend="g-main-context-push-thread-default">thread-default main
+ * loop</link> of the thread you are calling this method from. You can
+ * then call g_dbus_connection_close_finish() to get the result of the
+ * operation.  See g_dbus_connection_close_sync() for the synchronous
+ * version.
  *
  * Since: 2.26
  */
 void
-g_dbus_connection_close (GDBusConnection *connection)
+g_dbus_connection_close (GDBusConnection     *connection,
+                         GCancellable        *cancellable,
+                         GAsyncReadyCallback  callback,
+                         gpointer             user_data)
 {
+  GSimpleAsyncResult *simple;
+
   g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
 
+  simple = g_simple_async_result_new (NULL,
+                                      callback,
+                                      user_data,
+                                      g_dbus_connection_close);
+  g_simple_async_result_run_in_thread (simple,
+                                       close_in_thread_func,
+                                       G_PRIORITY_DEFAULT,
+                                       cancellable);
+  g_object_unref (simple);
+}
+
+/**
+ * g_dbus_connection_close_finish:
+ * @connection: A #GDBusConnection.
+ * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to g_dbus_connection_close().
+ * @error: Return location for error or %NULL.
+ *
+ * Finishes an operation started with g_dbus_connection_close().
+ *
+ * Returns: %TRUE if the operation succeeded, %FALSE if @error is set.
+ *
+ * Since: 2.26
+ */
+gboolean
+g_dbus_connection_close_finish (GDBusConnection  *connection,
+                                GAsyncResult     *res,
+                                GError          **error)
+{
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+  gboolean ret;
+
+  ret = FALSE;
+
+  g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE);
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_dbus_connection_close);
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    goto out;
+
+  ret = TRUE;
+
+ out:
+  return ret;
+}
+
+/**
+ * g_dbus_connection_close_sync:
+ * @connection: A #GDBusConnection.
+ * @cancellable: A #GCancellable or %NULL.
+ * @error: Return location for error or %NULL.
+ *
+ * Synchronously closees @connection. The calling thread is blocked
+ * until this is done. See g_dbus_connection_close() for the
+ * asynchronous version of this method and more details about what it
+ * does.
+ *
+ * Returns: %TRUE if the operation succeeded, %FALSE if @error is set.
+ *
+ * Since: 2.26
+ */
+gboolean
+g_dbus_connection_close_sync (GDBusConnection     *connection,
+                              GCancellable        *cancellable,
+                              GError             **error)
+{
+  gboolean ret;
+
+  g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  ret = FALSE;
+
   CONNECTION_LOCK (connection);
   if (!connection->closed)
     {
-      GError *error = NULL;
-
-      /* TODO: do this async */
-      //g_debug ("closing connection %p's stream %p", connection, connection->stream);
-      if (!g_io_stream_close (connection->stream, NULL, &error))
-        {
-          g_warning ("Error closing stream: %s", error->message);
-          g_error_free (error);
-        }
-
-      set_closed_unlocked (connection, FALSE, NULL);
+      ret = g_io_stream_close (connection->stream,
+                               cancellable,
+                               error);
+      if (ret)
+        set_closed_unlocked (connection, FALSE, NULL);
+    }
+  else
+    {
+      g_set_error_literal (error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_CLOSED,
+                           _("The connection is closed"));
     }
   CONNECTION_UNLOCK (connection);
+
+  return ret;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
index b9f8dc1eadb904c58205731539e451fcc96199c3..6dfb6fbbd20254724c60018c15de0c94bc83db58 100644 (file)
@@ -85,7 +85,6 @@ GDBusConnection *g_dbus_connection_new_for_address_sync       (const gchar
 
 void             g_dbus_connection_start_message_processing   (GDBusConnection    *connection);
 gboolean         g_dbus_connection_is_closed                  (GDBusConnection    *connection);
-void             g_dbus_connection_close                      (GDBusConnection    *connection);
 GIOStream       *g_dbus_connection_get_stream                 (GDBusConnection    *connection);
 const gchar     *g_dbus_connection_get_guid                   (GDBusConnection    *connection);
 const gchar     *g_dbus_connection_get_unique_name            (GDBusConnection    *connection);
@@ -97,6 +96,19 @@ GDBusCapabilityFlags  g_dbus_connection_get_capabilities      (GDBusConnection
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+void             g_dbus_connection_close                          (GDBusConnection     *connection,
+                                                                   GCancellable        *cancellable,
+                                                                   GAsyncReadyCallback  callback,
+                                                                   gpointer             user_data);
+gboolean         g_dbus_connection_close_finish                   (GDBusConnection     *connection,
+                                                                   GAsyncResult        *res,
+                                                                   GError             **error);
+gboolean         g_dbus_connection_close_sync                     (GDBusConnection     *connection,
+                                                                   GCancellable        *cancellable,
+                                                                   GError             **error);
+
+/* ---------------------------------------------------------------------------------------------------- */
+
 void             g_dbus_connection_flush                          (GDBusConnection     *connection,
                                                                    GCancellable        *cancellable,
                                                                    GAsyncReadyCallback  callback,
index 1163edfec79275d92cc1e8a852b9d21cc90dd037..62c961d31c93e2244c39b79e2be9d18f935c710e 100644 (file)
@@ -1539,6 +1539,8 @@ g_dbus_connection_get_unique_name
 g_dbus_connection_is_closed
 g_dbus_connection_set_exit_on_close
 g_dbus_connection_close
+g_dbus_connection_close_finish
+g_dbus_connection_close_sync
 g_dbus_connection_flush
 g_dbus_connection_flush_finish
 g_dbus_connection_flush_sync
index cd6aa0d2b3b9b67318b4e8572900f952d7bfaa90..417e66cdcc785e8f790e410a721114093ec2acd0 100644 (file)
@@ -39,6 +39,7 @@ static GMainLoop *loop = NULL;
 static void
 test_connection_life_cycle (void)
 {
+  gboolean ret;
   GDBusConnection *c;
   GDBusConnection *c2;
   GError *error;
@@ -88,9 +89,14 @@ test_connection_life_cycle (void)
   g_assert_no_error (error);
   g_assert (c2 != NULL);
   g_assert (!g_dbus_connection_is_closed (c2));
-  g_dbus_connection_close (c2);
+  ret = g_dbus_connection_close_sync (c2, NULL, &error);
+  g_assert_no_error (error);
+  g_assert (ret);
   _g_assert_signal_received (c2, "closed");
   g_assert (g_dbus_connection_is_closed (c2));
+  ret = g_dbus_connection_close_sync (c2, NULL, &error);
+  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED);
+  g_assert (!ret);
   g_object_unref (c2);
 
   /*