mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-26 08:50:07 +01:00
core: cache GVariant for result of GetSettings()
The GetSettings() call is not the only place where we convert a NMConnection to D-Bus. However it is one of the most prominent ones with a measurable performance overhead. The connection seldom changes, so it makes sense to cache it. Note that GetSettings() is the only caller that specifies an option, thus it's the only caller that converts a NMConnection to variant in this particular way. That means, other callers don't benefit from this caching and we could not cache the variant in the NMConnection instance itself, because those callers use different parameters.
This commit is contained in:
parent
cea52c7cbd
commit
252e4a676b
1 changed files with 62 additions and 5 deletions
|
|
@ -80,6 +80,11 @@ typedef struct _NMSettingsConnectionPrivate {
|
|||
|
||||
NMConnection *connection;
|
||||
|
||||
struct {
|
||||
NMConnectionSerializationOptions options;
|
||||
GVariant * variant;
|
||||
} getsettings_cached;
|
||||
|
||||
NMSettingsStorage *storage;
|
||||
|
||||
char *filename;
|
||||
|
|
@ -249,6 +254,57 @@ _seen_bssids_hash_new(void)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_getsettings_cached_clear(NMSettingsConnectionPrivate *priv)
|
||||
{
|
||||
if (nm_clear_pointer(&priv->getsettings_cached.variant, g_variant_unref)) {
|
||||
priv->getsettings_cached.options.timestamp.has = FALSE;
|
||||
priv->getsettings_cached.options.timestamp.val = 0;
|
||||
nm_clear_g_free((gpointer *) &priv->getsettings_cached.options.seen_bssids);
|
||||
}
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
_getsettings_cached_get(NMSettingsConnection *self, const NMConnectionSerializationOptions *options)
|
||||
{
|
||||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self);
|
||||
GVariant * variant;
|
||||
|
||||
if (priv->getsettings_cached.variant) {
|
||||
if (nm_connection_serialization_options_equal(&priv->getsettings_cached.options, options)) {
|
||||
#if NM_MORE_ASSERTS > 10
|
||||
gs_unref_variant GVariant *variant2 = NULL;
|
||||
|
||||
variant = nm_connection_to_dbus_full(priv->connection,
|
||||
NM_CONNECTION_SERIALIZE_WITH_NON_SECRET,
|
||||
options);
|
||||
nm_assert(variant);
|
||||
variant2 = g_variant_new("(@a{sa{sv}})", variant);
|
||||
nm_assert(g_variant_equal(priv->getsettings_cached.variant, variant2));
|
||||
#endif
|
||||
return priv->getsettings_cached.variant;
|
||||
}
|
||||
_getsettings_cached_clear(priv);
|
||||
}
|
||||
|
||||
nm_assert(!priv->getsettings_cached.options.seen_bssids);
|
||||
|
||||
variant = nm_connection_to_dbus_full(priv->connection,
|
||||
NM_CONNECTION_SERIALIZE_WITH_NON_SECRET,
|
||||
options);
|
||||
nm_assert(variant);
|
||||
|
||||
priv->getsettings_cached.variant = g_variant_ref_sink(g_variant_new("(@a{sa{sv}})", variant));
|
||||
|
||||
priv->getsettings_cached.options = *options;
|
||||
priv->getsettings_cached.options.seen_bssids =
|
||||
nm_utils_strv_dup_packed(priv->getsettings_cached.options.seen_bssids, -1);
|
||||
|
||||
return priv->getsettings_cached.variant;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMConnection *
|
||||
nm_settings_connection_get_connection(NMSettingsConnection *self)
|
||||
{
|
||||
|
|
@ -280,6 +336,8 @@ _nm_settings_connection_set_connection(NMSettingsConnection * self,
|
|||
priv->connection = g_object_ref(new_connection);
|
||||
nmtst_connection_assert_unchanging(priv->connection);
|
||||
|
||||
_getsettings_cached_clear(priv);
|
||||
|
||||
/* note that we only return @connection_old if the new connection actually differs from
|
||||
* before.
|
||||
*
|
||||
|
|
@ -1243,7 +1301,6 @@ get_settings_auth_cb(NMSettingsConnection * self,
|
|||
{
|
||||
gs_free const char ** seen_bssids = NULL;
|
||||
NMConnectionSerializationOptions options = {};
|
||||
GVariant * settings;
|
||||
|
||||
if (error) {
|
||||
g_dbus_method_invocation_return_gerror(context, error);
|
||||
|
|
@ -1270,10 +1327,8 @@ get_settings_auth_cb(NMSettingsConnection * self,
|
|||
* get returned by the GetSecrets method which can be better
|
||||
* protected against leakage of secrets to unprivileged callers.
|
||||
*/
|
||||
settings = nm_connection_to_dbus_full(nm_settings_connection_get_connection(self),
|
||||
NM_CONNECTION_SERIALIZE_WITH_NON_SECRET,
|
||||
&options);
|
||||
g_dbus_method_invocation_return_value(context, g_variant_new("(@a{sa{sv}})", settings));
|
||||
|
||||
g_dbus_method_invocation_return_value(context, _getsettings_cached_get(self, &options));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2620,6 +2675,8 @@ dispose(GObject *object)
|
|||
|
||||
g_clear_object(&priv->connection);
|
||||
|
||||
_getsettings_cached_clear(priv);
|
||||
|
||||
nm_clear_pointer(&priv->kf_db_timestamps, nm_key_file_db_unref);
|
||||
nm_clear_pointer(&priv->kf_db_seen_bssids, nm_key_file_db_unref);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue