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).
This commit is contained in:
Thomas Haller 2022-04-08 11:40:42 +02:00
parent cef5b8dd46
commit 6e35cf4a7d
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
2 changed files with 31 additions and 0 deletions

View file

@ -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);

View file

@ -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,