[libdazzle] cancellable: add chained cancellable helper



commit 61dbc7c7709a20f95593743bbc50c85048936677
Author: Christian Hergert <chergert redhat com>
Date:   Sun Dec 17 18:52:39 2017 -0800

    cancellable: add chained cancellable helper
    
    This tries to simplify the process of chaining cancellables
    together when you have complex, and often overlapping, async
    operations.

 src/dazzle.h               |    1 +
 src/util/dzl-cancellable.c |   60 ++++++++++++++++++++++++++++++++++++++++++++
 src/util/dzl-cancellable.h |   28 ++++++++++++++++++++
 src/util/meson.build       |    2 +
 tests/meson.build          |    7 +++++
 tests/test-cancellable.c   |   35 +++++++++++++++++++++++++
 6 files changed, 133 insertions(+), 0 deletions(-)
---
diff --git a/src/dazzle.h b/src/dazzle.h
index a0769c0..0e08b7a 100644
--- a/src/dazzle.h
+++ b/src/dazzle.h
@@ -129,6 +129,7 @@ G_BEGIN_DECLS
 #include "tree/dzl-tree-node.h"
 #include "tree/dzl-tree-types.h"
 #include "util/dzl-cairo.h"
+#include "util/dzl-cancellable.h"
 #include "util/dzl-counter.h"
 #include "util/dzl-date-time.h"
 #include "util/dzl-dnd.h"
diff --git a/src/util/dzl-cancellable.c b/src/util/dzl-cancellable.c
new file mode 100644
index 0000000..a84c340
--- /dev/null
+++ b/src/util/dzl-cancellable.c
@@ -0,0 +1,60 @@
+/* dzl-cancellable.c
+ *
+ * Copyright © 2017 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 "dzl-cancellable"
+
+#include <gio/gio.h>
+
+#include "util/dzl-cancellable.h"
+
+static void
+dzl_cancellable_cancelled_cb (GCancellable *dep,
+                              GCancellable *parent)
+{
+  g_assert (G_IS_CANCELLABLE (dep));
+  g_assert (G_IS_CANCELLABLE (parent));
+
+  if (!g_cancellable_is_cancelled (parent))
+    g_cancellable_cancel (parent);
+}
+
+/**
+ * dzl_cancellable_chain:
+ * @self: (nullable): a #GCancellable or %NULL
+ * @other: (nullable): a #GCancellable or %NULL
+ *
+ * If both @self and @other are not %NULL, then the cancellation of
+ * @other will be propagated to @self if @other is cancelled.
+ *
+ * Since: 3.28
+ */
+void
+dzl_cancellable_chain (GCancellable *self,
+                       GCancellable *other)
+{
+  g_return_if_fail (!self || G_IS_CANCELLABLE (self));
+  g_return_if_fail (!other || G_IS_CANCELLABLE (other));
+
+  if (self == NULL || other == NULL)
+    return;
+
+  g_cancellable_connect (other,
+                         G_CALLBACK (dzl_cancellable_cancelled_cb),
+                         g_object_ref (self),
+                         g_object_unref);
+}
diff --git a/src/util/dzl-cancellable.h b/src/util/dzl-cancellable.h
new file mode 100644
index 0000000..8622748
--- /dev/null
+++ b/src/util/dzl-cancellable.h
@@ -0,0 +1,28 @@
+/* dzl-cancellable.h
+ *
+ * Copyright © 2017 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/>.
+ */
+
+#pragma once
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+void dzl_cancellable_chain (GCancellable *cancellable,
+                            GCancellable *to_chain);
+
+G_END_DECLS
diff --git a/src/util/meson.build b/src/util/meson.build
index 276286a..f953b5f 100644
--- a/src/util/meson.build
+++ b/src/util/meson.build
@@ -1,5 +1,6 @@
 util_headers = [
   'dzl-cairo.h',
+  'dzl-cancellable.h',
   'dzl-date-time.h',
   'dzl-dnd.h',
   'dzl-file-manager.h',
@@ -16,6 +17,7 @@ util_headers = [
 
 util_sources = [
   'dzl-cairo.c',
+  'dzl-cancellable.c',
   'dzl-date-time.c',
   'dzl-dnd.c',
   'dzl-file-manager.c',
diff --git a/tests/meson.build b/tests/meson.build
index ac8dd20..8557261 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -363,4 +363,11 @@ test_tree = executable('test-tree', 'test-tree.c',
   dependencies: libdazzle_deps + [libdazzle_dep],
 )
 
+test_cancellable = executable('test-cancellable', 'test-cancellable.c',
+        c_args: test_cflags,
+     link_args: test_link_args,
+  dependencies: libdazzle_deps + [libdazzle_dep],
+)
+test('test-cancellable', test_cancellable, env: test_env)
+
 endif
diff --git a/tests/test-cancellable.c b/tests/test-cancellable.c
new file mode 100644
index 0000000..020a3c7
--- /dev/null
+++ b/tests/test-cancellable.c
@@ -0,0 +1,35 @@
+#include <dazzle.h>
+
+static void
+test_basic (void)
+{
+  g_autoptr(GCancellable) root = g_cancellable_new ();
+  g_autoptr(GCancellable) a = g_cancellable_new ();
+  g_autoptr(GCancellable) b = g_cancellable_new ();
+  g_autoptr(GCancellable) a1 = g_cancellable_new ();
+  g_autoptr(GCancellable) a2 = g_cancellable_new ();
+
+  dzl_cancellable_chain (root, a);
+  dzl_cancellable_chain (root, b);
+
+  dzl_cancellable_chain (a, a1);
+  dzl_cancellable_chain (a, a2);
+
+  g_cancellable_cancel (a2);
+
+  g_assert_cmpint (TRUE, ==, g_cancellable_is_cancelled (a2));
+  g_assert_cmpint (TRUE, ==, g_cancellable_is_cancelled (a));
+  g_assert_cmpint (TRUE, ==, g_cancellable_is_cancelled (root));
+
+  g_assert_cmpint (FALSE, ==, g_cancellable_is_cancelled (a1));
+  g_assert_cmpint (FALSE, ==, g_cancellable_is_cancelled (b));
+}
+
+gint
+main (gint   argc,
+      gchar *argv[])
+{
+  g_test_init (&argc, &argv, NULL);
+  g_test_add_func ("/Dazzle/Cancellable", test_basic);
+  return g_test_run ();
+}


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