[gnome-builder] glib: add g_task_return_* helpers



commit 1c7988e59c895db25721a077ee1a05efb829feca
Author: Christian Hergert <chergert redhat com>
Date:   Thu Sep 15 12:00:28 2016 -0700

    glib: add g_task_return_* helpers
    
    If we are currently in the active tasks GMainContext, we can end up
    returning immediately. We don't want to do that in some cases because we
    hold a lock that is internal to the data structure.
    
    This allows those situations to be explicit about the dispatch cycle.

 libide/Makefile.am     |    2 +
 libide/ide.h           |    1 +
 libide/util/ide-glib.c |  139 ++++++++++++++++++++++++++++++++++++++++++++++++
 libide/util/ide-glib.h |   36 ++++++++++++
 4 files changed, 178 insertions(+), 0 deletions(-)
---
diff --git a/libide/Makefile.am b/libide/Makefile.am
index cc1ef10..aa2e203 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -152,6 +152,7 @@ libide_1_0_la_public_headers =                            \
        util/ide-cairo.h                                  \
        util/ide-dnd.h                                    \
        util/ide-file-manager.h                           \
+       util/ide-glib.h                                   \
        util/ide-gtk.h                                    \
        util/ide-line-reader.h                            \
        util/ide-list-inline.h                            \
@@ -305,6 +306,7 @@ libide_1_0_la_public_sources =                            \
        util/ide-cairo.c                                  \
        util/ide-dnd.c                                    \
        util/ide-file-manager.c                           \
+       util/ide-glib.c                                   \
        util/ide-gtk.c                                    \
        util/ide-line-reader.c                            \
        util/ide-pango.c                                  \
diff --git a/libide/ide.h b/libide/ide.h
index 1b93c8e..fdb0dfc 100644
--- a/libide/ide.h
+++ b/libide/ide.h
@@ -130,6 +130,7 @@ G_BEGIN_DECLS
 #include "tree/ide-tree-types.h"
 #include "tree/ide-tree.h"
 #include "util/ide-file-manager.h"
+#include "util/ide-glib.h"
 #include "util/ide-gtk.h"
 #include "util/ide-line-reader.h"
 #include "util/ide-list-inline.h"
diff --git a/libide/util/ide-glib.c b/libide/util/ide-glib.c
new file mode 100644
index 0000000..36eecaa
--- /dev/null
+++ b/libide/util/ide-glib.c
@@ -0,0 +1,139 @@
+/* ide-glib.c
+ *
+ * Copyright (C) 2016 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "ide-glib"
+
+#include "ide-glib.h"
+
+typedef struct
+{
+  int type;
+  GTask *task;
+  union {
+    gboolean v_bool;
+    gint v_int;
+    struct {
+      gpointer pointer;
+      GDestroyNotify destroy;
+    } v_ptr;
+  } u;
+} TaskState;
+
+static gboolean
+do_return (gpointer user_data)
+{
+  TaskState *state = user_data;
+
+  switch (state->type)
+    {
+    case G_TYPE_INT:
+      g_task_return_int (state->task, state->u.v_int);
+      break;
+
+    case G_TYPE_BOOLEAN:
+      g_task_return_boolean (state->task, state->u.v_bool);
+      break;
+
+    case G_TYPE_POINTER:
+      g_task_return_pointer (state->task, state->u.v_ptr.pointer, state->u.v_ptr.destroy);
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+
+  g_clear_object (&state->task);
+  g_slice_free (TaskState, state);
+
+  return G_SOURCE_REMOVE;
+}
+
+static void
+task_state_attach (TaskState *state)
+{
+  GMainContext *main_context;
+  GSource *source;
+
+  g_assert (state != NULL);
+  g_assert (G_IS_TASK (state->task));
+
+  main_context = g_task_get_context (state->task);
+
+  source = g_timeout_source_new (0);
+  g_source_set_callback (source, do_return, state, NULL);
+  g_source_set_name (source, "[ide] ide_g_task_return_from_main");
+  g_source_attach (source, main_context);
+  g_source_unref (source);
+}
+
+/**
+ * ide_g_task_return_boolean_from_main:
+ *
+ * This is just like g_task_return_boolean() except that it enforces
+ * that the current stack return to the main context before dispatching
+ * the callback.
+ */
+void
+ide_g_task_return_boolean_from_main (GTask    *task,
+                                     gboolean  value)
+{
+  TaskState *state;
+
+  g_return_if_fail (G_IS_TASK (task));
+
+  state = g_slice_new0 (TaskState);
+  state->type = G_TYPE_BOOLEAN;
+  state->task = g_object_ref (task);
+  state->u.v_bool = !!value;
+
+  task_state_attach (state);
+}
+
+void
+ide_g_task_return_int_from_main (GTask *task,
+                                 gint   value)
+{
+  TaskState *state;
+
+  g_return_if_fail (G_IS_TASK (task));
+
+  state = g_slice_new0 (TaskState);
+  state->type = G_TYPE_INT;
+  state->task = g_object_ref (task);
+  state->u.v_int = value;
+
+  task_state_attach (state);
+}
+
+void
+ide_g_task_return_pointer_from_main (GTask          *task,
+                                     gpointer        value,
+                                     GDestroyNotify  notify)
+{
+  TaskState *state;
+
+  g_return_if_fail (G_IS_TASK (task));
+
+  state = g_slice_new0 (TaskState);
+  state->type = G_TYPE_POINTER;
+  state->task = g_object_ref (task);
+  state->u.v_ptr.pointer = value;
+  state->u.v_ptr.destroy = notify;
+
+  task_state_attach (state);
+}
diff --git a/libide/util/ide-glib.h b/libide/util/ide-glib.h
new file mode 100644
index 0000000..a43f6b3
--- /dev/null
+++ b/libide/util/ide-glib.h
@@ -0,0 +1,36 @@
+/* ide-glib.h
+ *
+ * Copyright (C) 2016 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IDE_GLIB_H
+#define IDE_GLIB_H
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+void ide_g_task_return_boolean_from_main (GTask          *task,
+                                          gboolean        value);
+void ide_g_task_return_int_from_main     (GTask          *task,
+                                          gint            value);
+void ide_g_task_return_pointer_from_main (GTask          *task,
+                                          gpointer        value,
+                                          GDestroyNotify  notify);
+
+G_END_DECLS
+
+#endif /* IDE_GLIB_H */


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