[glib] gmain: add g_clear_handle_id API
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] gmain: add g_clear_handle_id API
- Date: Tue, 7 Nov 2017 16:29:05 +0000 (UTC)
commit 5ebd8f6e88734c2a1c8574ff4af681a2eb9c74a5
Author: Cosimo Cecchi <cosimo endlessm com>
Date: Sat Sep 30 21:09:37 2017 -0700
gmain: add g_clear_handle_id API
It's a very common pattern to see code that looks like this in
dispose() or finalize() implementations:
if (priv->source_id > 0)
{
g_source_remove (priv->source_id);
priv->source_id = 0;
}
This API allows to accomplish the same goal with a single line:
g_clear_handle_id (&priv->source_id, (GClearHandleFunc) g_source_remove);
Thanks to Emmanuele Bassi <ebassi gnome org> for making the patch
generic.
https://bugzilla.gnome.org/show_bug.cgi?id=788489
docs/reference/glib/glib-sections.txt | 2 +
glib/gmain.c | 34 +++++++++++++++++++++++++++++++++
glib/gmain.h | 32 +++++++++++++++++++++++++++++++
glib/tests/utils.c | 26 +++++++++++++++++++++++++
4 files changed, 94 insertions(+), 0 deletions(-)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index 56376c0..1aaaf60 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -633,6 +633,8 @@ g_source_get_current_time
g_source_remove
g_source_remove_by_funcs_user_data
g_source_remove_by_user_data
+GClearHandleFunc
+g_clear_handle_id
<SUBSECTION Private>
GLIB_HAVE_ALLOCA_H
diff --git a/glib/gmain.c b/glib/gmain.c
index 3be0afc..bd77508 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -2413,6 +2413,40 @@ g_source_remove_by_funcs_user_data (GSourceFuncs *funcs,
return FALSE;
}
+/**
+ * g_clear_handle_id: (skip)
+ * @tag_ptr: (not nullable): a pointer to the handler ID
+ * @clear_func: (not nullable): the function to call to clear the handler
+ *
+ * Clears a numeric handler, such as a #GSource ID.
+ *
+ * @tag_ptr must be a valid pointer to the variable holding the handler.
+ *
+ * If the ID is zero then this function does nothing.
+ * Otherwise, clear_func() is called with the ID as a parameter, and the tag is
+ * set to zero.
+ *
+ * A macro is also included that allows this function to be used without
+ * pointer casts.
+ *
+ * Since: 2.56
+ */
+#undef g_clear_handle_id
+void
+g_clear_handle_id (guint *tag_ptr,
+ GClearHandleFunc clear_func)
+{
+ guint _handle_id;
+
+ _handle_id = *tag_ptr;
+ if (_handle_id > 0)
+ {
+ *tag_ptr = 0;
+ if (clear_func != NULL)
+ clear_func (_handle_id);
+ }
+}
+
#ifdef G_OS_UNIX
/**
* g_source_add_unix_fd:
diff --git a/glib/gmain.h b/glib/gmain.h
index 4979927..efd7052 100644
--- a/glib/gmain.h
+++ b/glib/gmain.h
@@ -563,6 +563,38 @@ GLIB_AVAILABLE_IN_ALL
gboolean g_source_remove_by_funcs_user_data (GSourceFuncs *funcs,
gpointer user_data);
+/**
+ * GClearHandleFunc:
+ * @handle_id: the handle ID to clear
+ *
+ * Specifies the type of function passed to g_clear_handle_id().
+ * The implementation is expected to free the resource identified
+ * by @handle_id; for instance, if @handle_id is a #GSource ID,
+ * g_source_remove() can be used.
+ *
+ * Since: 2.56
+ */
+typedef void (* GClearHandleFunc) (guint handle_id);
+
+GLIB_AVAILABLE_IN_2_56
+void g_clear_handle_id (guint *tag_ptr,
+ GClearHandleFunc clear_func);
+
+#define g_clear_handle_id(tag_ptr, clear_func) \
+ G_STMT_START { \
+ G_STATIC_ASSERT (sizeof *(tag_ptr) == sizeof (guint)); \
+ guint *_tag_ptr = (guint *) (tag_ptr); \
+ guint _handle_id; \
+ \
+ _handle_id = *_tag_ptr; \
+ if (_handle_id > 0) \
+ { \
+ *_tag_ptr = 0; \
+ if (clear_func != NULL) \
+ clear_func (_handle_id); \
+ } \
+ } G_STMT_END
+
/* Idles, child watchers and timeouts */
GLIB_AVAILABLE_IN_ALL
guint g_timeout_add_full (gint priority,
diff --git a/glib/tests/utils.c b/glib/tests/utils.c
index c7a1f6e..7f8edd8 100644
--- a/glib/tests/utils.c
+++ b/glib/tests/utils.c
@@ -478,6 +478,31 @@ test_desktop_special_dir (void)
g_assert (dir2 != NULL);
}
+static gboolean
+source_test (gpointer data)
+{
+ g_assert_not_reached ();
+ return G_SOURCE_REMOVE;
+}
+
+static void
+test_clear_source (void)
+{
+ guint id;
+
+ id = g_idle_add (source_test, NULL);
+ g_assert_cmpuint (id, >, 0);
+
+ g_clear_handle_id (&id, g_source_remove);
+ g_assert_cmpuint (id, ==, 0);
+
+ id = g_timeout_add (100, source_test, NULL);
+ g_assert_cmpuint (id, >, 0);
+
+ g_clear_handle_id (&id, g_source_remove);
+ g_assert_cmpuint (id, ==, 0);
+}
+
static void
test_clear_pointer (void)
{
@@ -632,6 +657,7 @@ main (int argc,
g_test_add_func ("/utils/specialdir/desktop", test_desktop_special_dir);
g_test_add_func ("/utils/clear-pointer", test_clear_pointer);
g_test_add_func ("/utils/take-pointer", test_take_pointer);
+ g_test_add_func ("/utils/clear-source", test_clear_source);
g_test_add_func ("/utils/misc-mem", test_misc_mem);
g_test_add_func ("/utils/nullify", test_nullify);
g_test_add_func ("/utils/atexit", test_atexit);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]