From 6e35cf4a7d709385b7c8e38ab41f8e62873a34eb Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 8 Apr 2022 11:40:42 +0200 Subject: [PATCH] core: add nm_manager_get_dns_manager() getter nm_dns_manager_get() is already a singleton. So users usually can just get it whenever they need -- except during shutdown after the singleton was destroyed. This is usually fine, because users really should not try to get it late during shutdown. However, if you subscribe a signal handler on the singleton, then you will also eventually want to unsubscribe it. While the moment when you subscribe it is clearly not during late-shutdown, it's not clear how to ensure that the signal listener gets destroyed before the DNS manager singleton. So usually, whenever you are going to subscribe a signal, you need to make sure that the target object stays alive long enough. Which may mean to keep a reference to it. Next, we will have NMDevice subscribe to the singleton. With above said, that would mean that potentially every NMDevice needs to keep a reference to the NMDnsManager. That is not best. Also, later NMManager will face the same problem, because it will also subscribe to NMDnsManager. So, instead let NMManager own a reference to the NMDnsManager. This ensures the lifetimes are properly guarded (NMDevice also references NMManager already). Also, access nm_dns_manager_get() lazy on first use, to only initialize it when needed the first time (which might be quite late). --- src/core/nm-manager.c | 27 +++++++++++++++++++++++++++ src/core/nm-manager.h | 4 ++++ 2 files changed, 31 insertions(+) diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c index 521536979f..fab316f4d4 100644 --- a/src/core/nm-manager.c +++ b/src/core/nm-manager.c @@ -20,6 +20,7 @@ #include "devices/nm-device-factory.h" #include "devices/nm-device-generic.h" #include "devices/nm-device.h" +#include "dns/nm-dns-manager.h" #include "dhcp/nm-dhcp-manager.h" #include "libnm-core-aux-intern/nm-common-macros.h" #include "libnm-core-intern/nm-core-internal.h" @@ -144,6 +145,8 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMManager, typedef struct { NMPlatform *platform; + NMDnsManager *dns_mgr; + GArray *capabilities; CList active_connections_lst_head; /* Oldest ACs at the beginning */ @@ -7790,6 +7793,28 @@ impl_manager_checkpoint_adjust_rollback_timeout(NMDBusObject /*****************************************************************************/ +NMDnsManager * +nm_manager_get_dns_manager(NMManager *self) +{ + NMManagerPrivate *priv; + + g_return_val_if_fail(NM_IS_MANAGER(self), NULL); + + priv = NM_MANAGER_GET_PRIVATE(self); + + if (G_UNLIKELY(!priv->dns_mgr)) { + /* Initialize lazily on first use. + * + * But keep a reference. This is to ensure proper lifetimes between + * singleton instances (i.e. nm_dns_manager_get() outlives NMManager). */ + priv->dns_mgr = g_object_ref(nm_dns_manager_get()); + } + + return priv->dns_mgr; +} + +/*****************************************************************************/ + static void auth_mgr_changed(NMAuthManager *auth_manager, gpointer user_data) { @@ -8250,6 +8275,8 @@ dispose(GObject *object) g_clear_object(&priv->concheck_mgr); } + g_clear_object(&priv->dns_mgr); + if (priv->auth_mgr) { g_signal_handlers_disconnect_by_func(priv->auth_mgr, G_CALLBACK(auth_mgr_changed), self); g_clear_object(&priv->auth_mgr); diff --git a/src/core/nm-manager.h b/src/core/nm-manager.h index f8563c3aa1..fcb0022720 100644 --- a/src/core/nm-manager.h +++ b/src/core/nm-manager.h @@ -200,6 +200,10 @@ NMMetered nm_manager_get_metered(NMManager *self); void nm_manager_notify_device_availability_maybe_changed(NMManager *self); +struct _NMDnsManager; + +struct _NMDnsManager *nm_manager_get_dns_manager(NMManager *self); + /*****************************************************************************/ void nm_manager_device_auth_request(NMManager *self,