[gnome-builder/wip/chergert/debugger: 42/58] mi2: move client cleanup into dispose handler
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/debugger: 42/58] mi2: move client cleanup into dispose handler
- Date: Sun, 26 Mar 2017 07:24:53 +0000 (UTC)
commit d9796b1f5fb53587feba7ee6b8ebdad7c78d6bd3
Author: Christian Hergert <chergert redhat com>
Date: Sat Mar 25 15:36:42 2017 -0700
mi2: move client cleanup into dispose handler
We want to start cleaning this stuff up earlier to break referencing
issues. I still see a segfault when dealing with python callbacks, but
that requires more investigation.
contrib/mi2/mi2-client.c | 63 +++++++++++++++++++++++++++++++++++++++++----
1 files changed, 57 insertions(+), 6 deletions(-)
---
diff --git a/contrib/mi2/mi2-client.c b/contrib/mi2/mi2-client.c
index 630a720..a7ee629 100644
--- a/contrib/mi2/mi2-client.c
+++ b/contrib/mi2/mi2-client.c
@@ -60,6 +60,36 @@ G_DEFINE_TYPE_WITH_PRIVATE (Mi2Client, mi2_client, G_TYPE_OBJECT)
static GParamSpec *properties [N_PROPS];
static guint signals [N_SIGNALS];
+static void
+mi2_client_cancel_all_tasks (Mi2Client *self)
+{
+ Mi2ClientPrivate *priv = mi2_client_get_instance_private (self);
+ GList *list;
+
+ g_assert (MI2_IS_CLIENT (self));
+
+ g_queue_foreach (&priv->exec_commands, (GFunc)g_object_unref, NULL);
+ g_queue_clear (&priv->exec_commands);
+
+ list = priv->exec_tasks.head;
+
+ priv->exec_tasks.head = NULL;
+ priv->exec_tasks.tail = NULL;
+ priv->exec_tasks.length = 0;
+
+ for (const GList *iter = list; iter != NULL; iter = iter->next)
+ {
+ g_autoptr(GTask) task = iter->data;
+
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_CANCELLED,
+ "The operation was cancelled");
+ }
+
+ g_list_free (list);
+}
+
static gboolean
mi2_client_check_ready (Mi2Client *self,
GError **error)
@@ -77,6 +107,24 @@ mi2_client_check_ready (Mi2Client *self,
return FALSE;
}
+ if (priv->read_loop_cancellable == NULL)
+ {
+ 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->read_loop_cancellable))
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_CANCELLED,
+ "The client has already been shutdown");
+ return FALSE;
+ }
+
return TRUE;
}
@@ -120,22 +168,24 @@ mi2_client_real_event (Mi2Client *self,
}
static void
-mi2_client_finalize (GObject *object)
+mi2_client_dispose (GObject *object)
{
Mi2Client *self = (Mi2Client *)object;
Mi2ClientPrivate *priv = mi2_client_get_instance_private (self);
+ mi2_client_cancel_all_tasks (self);
+
g_clear_object (&priv->io_stream);
g_clear_object (&priv->input_stream);
g_clear_object (&priv->output_stream);
g_clear_object (&priv->read_loop_cancellable);
- g_queue_foreach (&priv->exec_tasks, (GFunc)g_object_unref, NULL);
- g_queue_clear (&priv->exec_tasks);
-
- g_queue_foreach (&priv->exec_commands, (GFunc)g_object_unref, NULL);
- g_queue_clear (&priv->exec_commands);
+ G_OBJECT_CLASS (mi2_client_parent_class)->dispose (object);
+}
+static void
+mi2_client_finalize (GObject *object)
+{
G_OBJECT_CLASS (mi2_client_parent_class)->finalize (object);
}
@@ -183,6 +233,7 @@ mi2_client_class_init (Mi2ClientClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->dispose = mi2_client_dispose;
object_class->finalize = mi2_client_finalize;
object_class->get_property = mi2_client_get_property;
object_class->set_property = mi2_client_set_property;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]