summaryrefslogtreecommitdiff
path: root/src/NetworkManagerUtils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/NetworkManagerUtils.c')
-rw-r--r--src/NetworkManagerUtils.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c
index c866c5f496..c9a7e13fed 100644
--- a/src/NetworkManagerUtils.c
+++ b/src/NetworkManagerUtils.c
@@ -112,6 +112,53 @@ _nm_utils_set_testing (NMUtilsTestFlags flags)
}
}
+/*****************************************************************************/
+
+static GSList *_singletons = NULL;
+static gboolean _singletons_shutdown = FALSE;
+
+static void
+_nm_singleton_instance_weak_cb (gpointer data,
+ GObject *where_the_object_was)
+{
+ _singletons = g_slist_remove (_singletons, where_the_object_was);
+}
+
+static void __attribute__((destructor))
+_nm_singleton_instance_destroy (void)
+{
+ _singletons_shutdown = TRUE;
+
+ while (_singletons) {
+ GObject *instance = _singletons->data;
+
+ _singletons = g_slist_delete_link (_singletons, _singletons);
+
+ g_object_weak_unref (instance, _nm_singleton_instance_weak_cb, NULL);
+
+ if (instance->ref_count > 1)
+ nm_log_dbg (LOGD_CORE, "disown %s singleton (%p). There are more references and the instance might leak", G_OBJECT_TYPE_NAME (instance), instance);
+
+ g_object_unref (instance);
+ }
+}
+
+void
+_nm_singleton_instance_register_destruction (GObject *instance)
+{
+ g_return_if_fail (G_IS_OBJECT (instance));
+
+ /* Don't allow registration after shutdown. We only destroy the singletons
+ * once. */
+ g_return_if_fail (!_singletons_shutdown);
+
+ g_object_weak_ref (instance, _nm_singleton_instance_weak_cb, NULL);
+
+ _singletons = g_slist_prepend (_singletons, instance);
+}
+
+/*****************************************************************************/
+
/*
* nm_ethernet_address_is_valid:
* @addr: pointer to a binary or ASCII Ethernet address