[glib] GDBusConnection: Fix up g_dbus_connection_close()



commit 914b046226c762bae578e17f7ed9a0fdf058045a
Author: David Zeuthen <davidz redhat com>
Date:   Wed Jul 14 12:37:32 2010 -0400

    GDBusConnection: Fix up g_dbus_connection_close()
    
    ... 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 |    2 +
 gio/gdbusconnection.c               |  151 +++++++++++++++++++++++++++++++----
 gio/gdbusconnection.h               |   14 +++-
 gio/gio.symbols                     |    2 +
 gio/tests/gdbus-connection.c        |    8 ++-
 5 files changed, 158 insertions(+), 19 deletions(-)
---
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index efbaf90..e0d5b8c 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -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
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index 80f1fe4..7290e20 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -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;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
diff --git a/gio/gdbusconnection.h b/gio/gdbusconnection.h
index b9f8dc1..6dfb6fb 100644
--- a/gio/gdbusconnection.h
+++ b/gio/gdbusconnection.h
@@ -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,
diff --git a/gio/gio.symbols b/gio/gio.symbols
index 1163edf..62c961d 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -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
diff --git a/gio/tests/gdbus-connection.c b/gio/tests/gdbus-connection.c
index cd6aa0d..417e66c 100644
--- a/gio/tests/gdbus-connection.c
+++ b/gio/tests/gdbus-connection.c
@@ -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);
 
   /*



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