summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Trevisan (Treviño) <mail@3v1n0.net>2019-05-07 22:39:14 -0500
committerMarco Trevisan (Treviño) <mail@3v1n0.net>2019-05-20 13:33:41 -0500
commit409c1522bc8b5189c0f890177b13a12a66926cb1 (patch)
treed279cbbf1c1f5bcce3d5dd48f5010f8b7612296f
parent32ea5b7e1f08709db9207528b3859f4c0e1ed8b3 (diff)
downloadglib-409c1522bc8b5189c0f890177b13a12a66926cb1.tar.gz
gisgnal: Add g_clear_signal_handler
It allows to disconnect a signal handler from GObject instance and at the same time to nullify the signal handler. Provided also a macro for handler type conversion.
-rw-r--r--docs/reference/gobject/gobject-sections.txt1
-rw-r--r--gobject/gsignal.c30
-rw-r--r--gobject/gsignal.h15
3 files changed, 46 insertions, 0 deletions
diff --git a/docs/reference/gobject/gobject-sections.txt b/docs/reference/gobject/gobject-sections.txt
index d1fc4bdc1..2247888d1 100644
--- a/docs/reference/gobject/gobject-sections.txt
+++ b/docs/reference/gobject/gobject-sections.txt
@@ -861,6 +861,7 @@ g_signal_get_invocation_hint
g_signal_type_cclosure_new
g_signal_accumulator_first_wins
g_signal_accumulator_true_handled
+g_clear_signal_handler
<SUBSECTION Private>
g_signal_handlers_destroy
</SECTION>
diff --git a/gobject/gsignal.c b/gobject/gsignal.c
index 34102c150..551780327 100644
--- a/gobject/gsignal.c
+++ b/gobject/gsignal.c
@@ -3893,3 +3893,33 @@ g_signal_accumulator_first_wins (GSignalInvocationHint *ihint,
g_value_copy (handler_return, return_accu);
return FALSE;
}
+
+/**
+ * g_clear_signal_handler:
+ * @handler_id_ptr: A pointer to a handler ID (of type #gulong) of the handler to be disconnected.
+ * @instance: (type GObject.Object): The instance to remove the signal handler from.
+ *
+ * Disconnects a handler from @instance so it will not be called during
+ * any future or currently ongoing emissions of the signal it has been
+ * connected to. The @handler_id_ptr is then set to zero, which is never a valid handler ID value (see g_signal_connect()).
+ *
+ * If the handler ID is 0 then this function does nothing.
+ *
+ * A macro is also included that allows this function to be used without
+ * pointer casts.
+ *
+ * Since: 2.62
+ */
+#undef g_clear_signal_handler
+void
+g_clear_signal_handler (gulong *handler_id_ptr,
+ gpointer instance)
+{
+ g_return_if_fail (handler_id_ptr != NULL);
+
+ if (*handler_id_ptr != 0)
+ {
+ g_signal_handler_disconnect (instance, *handler_id_ptr);
+ *handler_id_ptr = 0;
+ }
+}
diff --git a/gobject/gsignal.h b/gobject/gsignal.h
index 97f847944..7825a863b 100644
--- a/gobject/gsignal.h
+++ b/gobject/gsignal.h
@@ -436,6 +436,21 @@ guint g_signal_handlers_disconnect_matched (gpointer instance,
gpointer func,
gpointer data);
+GLIB_AVAILABLE_IN_2_62
+void g_clear_signal_handler (gulong *handler_id_ptr,
+ gpointer instance);
+
+#define g_clear_signal_handler(handler_id_ptr, instance) \
+ G_STMT_START { \
+ G_STATIC_ASSERT (sizeof *(handler_id_ptr) == sizeof (gulong)); \
+ gulong _handler_id = *(handler_id_ptr); \
+ \
+ if (_handler_id > 0) \
+ { \
+ g_signal_handler_disconnect ((instance), _handler_id); \
+ *(handler_id_ptr) = 0; \
+ } \
+ } G_STMT_END
/* --- overriding and chaining --- */
GLIB_AVAILABLE_IN_ALL