[glib] GDBusConnection: Fix up g_dbus_connection_close()
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] GDBusConnection: Fix up g_dbus_connection_close()
- Date: Wed, 14 Jul 2010 16:41:32 +0000 (UTC)
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]