[gnome-builder/wip/chergert/debugger: 123/163] mi2: close IOStream instead of using cancellable
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/debugger: 123/163] mi2: close IOStream instead of using cancellable
- Date: Tue, 9 May 2017 00:55:21 +0000 (UTC)
commit d5b747012e0ba3e8ddfbfca6f95f6cff91e044ee
Author: Christian Hergert <chergert redhat com>
Date: Sat Mar 25 17:44:20 2017 -0700
mi2: close IOStream instead of using cancellable
The cancellable issue got us into very weird state, so instead we use
GIOStream to cancel the operation by closing it.
contrib/mi2/mi2-client.c | 80 ++++++++++++++++++++++++--------------------
contrib/mi2/test-client.c | 4 +-
2 files changed, 46 insertions(+), 38 deletions(-)
---
diff --git a/contrib/mi2/mi2-client.c b/contrib/mi2/mi2-client.c
index adbc162..d39302d 100644
--- a/contrib/mi2/mi2-client.c
+++ b/contrib/mi2/mi2-client.c
@@ -33,7 +33,6 @@ typedef struct
GIOStream *io_stream;
Mi2InputStream *input_stream;
Mi2OutputStream *output_stream;
- GCancellable *listen_cancellable;
GQueue exec_tasks;
GQueue exec_commands;
} Mi2ClientPrivate;
@@ -96,7 +95,7 @@ mi2_client_check_ready (Mi2Client *self,
g_return_val_if_fail (MI2_IS_CLIENT (self), FALSE);
- if (priv->input_stream == NULL || priv->output_stream == NULL)
+ if (priv->io_stream == NULL || priv->input_stream == NULL || priv->output_stream == NULL)
{
g_set_error (error,
G_IO_ERROR,
@@ -105,20 +104,11 @@ mi2_client_check_ready (Mi2Client *self,
return FALSE;
}
- if (priv->listen_cancellable == NULL)
+ if (g_io_stream_is_closed (priv->io_stream))
{
g_set_error (error,
G_IO_ERROR,
- G_IO_ERROR_NOT_CONNECTED,
- "You must call mi2_client_start_listening() first");
- return FALSE;
- }
-
- if (g_cancellable_is_cancelled (priv->listen_cancellable))
- {
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_CANCELLED,
+ G_IO_ERROR_CLOSED,
"The client has already been shutdown");
return FALSE;
}
@@ -176,7 +166,6 @@ mi2_client_dispose (GObject *object)
g_clear_object (&priv->io_stream);
g_clear_object (&priv->input_stream);
g_clear_object (&priv->output_stream);
- g_clear_object (&priv->listen_cancellable);
G_OBJECT_CLASS (mi2_client_parent_class)->dispose (object);
}
@@ -187,6 +176,8 @@ mi2_client_finalize (GObject *object)
Mi2Client *self = (Mi2Client *)object;
Mi2ClientPrivate *priv = mi2_client_get_instance_private (self);
+ g_print ("*************** finalize\n");
+
g_assert (priv->exec_commands.length == 0);
g_assert (priv->exec_commands.head == NULL);
g_assert (priv->exec_commands.tail == NULL);
@@ -564,26 +555,12 @@ mi2_client_listen_async (Mi2Client *self,
g_return_if_fail (MI2_IS_CLIENT (self));
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
- if (priv->listen_cancellable != NULL)
- {
- g_task_report_new_error (self, callback, user_data,
- mi2_client_listen_async,
- G_IO_ERROR,
- G_IO_ERROR_INVAL,
- "You are already listening");
- return;
- }
-
- if (cancellable != NULL)
- priv->listen_cancellable = g_object_ref (cancellable);
- else
- priv->listen_cancellable = g_cancellable_new ();
-
- task = g_task_new (self, priv->listen_cancellable, callback, user_data);
+ task = g_task_new (self, cancellable, callback, user_data);
g_task_set_source_tag (task, mi2_client_listen_async);
+ g_task_set_return_on_cancel (task, TRUE);
mi2_input_stream_read_message_async (priv->input_stream,
- priv->listen_cancellable,
+ NULL,
mi2_client_read_loop_cb,
g_steal_pointer (&task));
}
@@ -603,10 +580,39 @@ mi2_client_listen_finish (Mi2Client *self,
GAsyncResult *result,
GError **error)
{
+ g_autoptr(GError) local_error = NULL;
+
g_return_val_if_fail (MI2_IS_CLIENT (self), FALSE);
g_return_val_if_fail (G_IS_TASK (result), FALSE);
- return g_task_propagate_boolean (G_TASK (result), error);
+ if (!g_task_propagate_boolean (G_TASK (result), &local_error))
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CLOSED))
+ return TRUE;
+ g_propagate_error (error, g_steal_pointer (&local_error));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+mi2_client_shutdown_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GIOStream *io_stream = (GIOStream *)object;
+ g_autoptr(GTask) task = user_data;
+ g_autoptr(GError) error = NULL;
+
+ g_return_if_fail (G_IS_IO_STREAM (io_stream));
+ g_return_if_fail (G_IS_ASYNC_RESULT (result));
+ g_return_if_fail (G_IS_TASK (task));
+
+ if (!g_io_stream_close_finish (io_stream, result, &error))
+ g_task_return_error (task, g_steal_pointer (&error));
+ else
+ g_task_return_boolean (task, TRUE);
}
/**
@@ -632,16 +638,18 @@ mi2_client_shutdown_async (Mi2Client *self,
g_return_if_fail (MI2_IS_CLIENT (self));
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (G_IS_IO_STREAM (priv->io_stream));
task = g_task_new (self, cancellable, callback, user_data);
g_task_set_source_tag (task, mi2_client_shutdown_async);
mi2_client_cancel_all_tasks (self);
- if (!g_cancellable_is_cancelled (priv->listen_cancellable))
- g_cancellable_cancel (priv->listen_cancellable);
-
- g_task_return_boolean (task, TRUE);
+ g_io_stream_close_async (priv->io_stream,
+ G_PRIORITY_LOW,
+ NULL,
+ mi2_client_shutdown_cb,
+ g_steal_pointer (&task));
}
/**
diff --git a/contrib/mi2/test-client.c b/contrib/mi2/test-client.c
index 917de82..c43c09e 100644
--- a/contrib/mi2/test-client.c
+++ b/contrib/mi2/test-client.c
@@ -259,8 +259,8 @@ listen_done_cb (GObject *object,
g_print ("Listen operation completed\n");
r = mi2_client_listen_finish (MI2_CLIENT (object), result, &error);
- g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
- g_assert_cmpint (r, ==, FALSE);
+ g_assert_no_error (error);
+ g_assert_cmpint (r, ==, TRUE);
g_main_loop_quit (main_loop);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]