summaryrefslogtreecommitdiff
path: root/libnm-core/nm-setting-vpn.c
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-03-26 13:03:19 +0100
committerThomas Haller <thaller@redhat.com>2020-04-04 19:51:34 +0200
commit7047fd212e9be59780a9616844ab31ed2278992e (patch)
tree8f38614d4eff4372c3205bf6e95fddda0e4af028 /libnm-core/nm-setting-vpn.c
parent68328e0f2146e467f530519931cdd2e84f63bacf (diff)
downloadNetworkManager-7047fd212e9be59780a9616844ab31ed2278992e.tar.gz
libnm: allocate "data" hash for NMSettingVpn lazily
We always initialized priv->data in nm_setting_vpn_init(), but usually soon after this hash would be replaced by NM_SETTING_VPN_DATA property setter. Avoid that. Allow for priv->data to be %NULL, which of course has the meaning that no keys are set.
Diffstat (limited to 'libnm-core/nm-setting-vpn.c')
-rw-r--r--libnm-core/nm-setting-vpn.c76
1 files changed, 47 insertions, 29 deletions
diff --git a/libnm-core/nm-setting-vpn.c b/libnm-core/nm-setting-vpn.c
index 6d255b5c8e..76103d0c1f 100644
--- a/libnm-core/nm-setting-vpn.c
+++ b/libnm-core/nm-setting-vpn.c
@@ -81,6 +81,16 @@ G_DEFINE_TYPE (NMSettingVpn, nm_setting_vpn, NM_TYPE_SETTING)
/*****************************************************************************/
+static GHashTable *
+_ensure_strdict (GHashTable **p_hash)
+{
+ if (!*p_hash)
+ *p_hash = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free);
+ return *p_hash;
+}
+
+/*****************************************************************************/
+
/**
* nm_setting_vpn_get_service_type:
* @setting: the #NMSettingVpn
@@ -139,7 +149,7 @@ nm_setting_vpn_get_num_data_items (NMSettingVpn *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VPN (setting), 0);
- return g_hash_table_size (NM_SETTING_VPN_GET_PRIVATE (setting)->data);
+ return nm_g_hash_table_size (NM_SETTING_VPN_GET_PRIVATE (setting)->data);
}
/**
@@ -161,8 +171,9 @@ nm_setting_vpn_add_data_item (NMSettingVpn *setting,
g_return_if_fail (key && key[0]);
g_return_if_fail (item && item[0]);
- g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->data,
- g_strdup (key), g_strdup (item));
+ g_hash_table_insert (_ensure_strdict (&NM_SETTING_VPN_GET_PRIVATE (setting)->data),
+ g_strdup (key),
+ g_strdup (item));
_notify (setting, PROP_DATA);
}
@@ -181,7 +192,7 @@ nm_setting_vpn_get_data_item (NMSettingVpn *setting, const char *key)
{
g_return_val_if_fail (NM_IS_SETTING_VPN (setting), NULL);
- return (const char *) g_hash_table_lookup (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key);
+ return nm_g_hash_table_lookup (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key);:
}
/**
@@ -222,15 +233,14 @@ nm_setting_vpn_get_data_keys (NMSettingVpn *setting,
gboolean
nm_setting_vpn_remove_data_item (NMSettingVpn *setting, const char *key)
{
- gboolean found;
-
g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE);
g_return_val_if_fail (key, FALSE);
- found = g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key);
- if (found)
+ if (nm_g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key)) {
_notify (setting, PROP_DATA);
- return found;
+ return TRUE;
+ }
+ return FALSE;
}
static void
@@ -460,20 +470,22 @@ aggregate (NMSetting *setting,
/* Ok, we have no secrets with system-secret flags.
* But do we have any secret-flags (without secrets) that indicate system secrets? */
- g_hash_table_iter_init (&iter, priv->data);
- while (g_hash_table_iter_next (&iter, (gpointer *) &key_name, NULL)) {
- gs_free char *secret_name = NULL;
+ if (priv->data) {
+ g_hash_table_iter_init (&iter, priv->data);
+ while (g_hash_table_iter_next (&iter, (gpointer *) &key_name, NULL)) {
+ gs_free char *secret_name = NULL;
- if (!NM_STR_HAS_SUFFIX (key_name, "-flags"))
- continue;
- secret_name = g_strndup (key_name, strlen (key_name) - NM_STRLEN ("-flags"));
- if (secret_name[0] == '\0')
- continue;
- if (!nm_setting_get_secret_flags (NM_SETTING (setting), secret_name, &secret_flags, NULL))
- nm_assert_not_reached ();
- if (secret_flags == NM_SETTING_SECRET_FLAG_NONE) {
- *((gboolean *) arg) = TRUE;
- return TRUE;
+ if (!NM_STR_HAS_SUFFIX (key_name, "-flags"))
+ continue;
+ secret_name = g_strndup (key_name, strlen (key_name) - NM_STRLEN ("-flags"));
+ if (secret_name[0] == '\0')
+ continue;
+ if (!nm_setting_get_secret_flags (NM_SETTING (setting), secret_name, &secret_flags, NULL))
+ nm_assert_not_reached ();
+ if (secret_flags == NM_SETTING_SECRET_FLAG_NONE) {
+ *((gboolean *) arg) = TRUE;
+ return TRUE;
+ }
}
}
@@ -725,7 +737,8 @@ get_secret_flags (NMSetting *setting,
flags_key = nm_construct_name_a ("%s-flags", secret_name, &flags_key_free);
- if (!g_hash_table_lookup_extended (priv->data, flags_key, NULL, (gpointer *) &flags_val)) {
+ if ( !priv->data
+ || !g_hash_table_lookup_extended (priv->data, flags_key, NULL, (gpointer *) &flags_val)) {
NM_SET_OUT (out_flags, NM_SETTING_SECRET_FLAG_NONE);
/* having no secret flag for the secret is fine, as long as there
@@ -771,7 +784,7 @@ set_secret_flags (NMSetting *setting,
return FALSE;
}
- g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->data,
+ g_hash_table_insert (_ensure_strdict (&NM_SETTING_VPN_GET_PRIVATE (setting)->data),
g_strdup_printf ("%s-flags", secret_name),
g_strdup_printf ("%u", flags));
_notify (NM_SETTING_VPN (setting), PROP_SECRETS);
@@ -997,9 +1010,14 @@ set_property (GObject *object, guint prop_id,
case PROP_PERSISTENT:
priv->persistent = g_value_get_boolean (value);
break;
- case PROP_DATA:
- g_hash_table_unref (priv->data);
- priv->data = _nm_utils_copy_strdict (g_value_get_boxed (value));
+ case PROP_DATA: {
+ _nm_unused gs_unref_hashtable GHashTable *data_free = g_steal_pointer (&priv->data);
+ GHashTable *hash = g_value_get_boxed (value);
+
+ if ( hash
+ && g_hash_table_size (hash) > 0)
+ priv->data = _nm_utils_copy_strdict (hash);
+ }
break;
case PROP_SECRETS:
g_hash_table_unref (priv->secrets);
@@ -1021,7 +1039,6 @@ nm_setting_vpn_init (NMSettingVpn *setting)
{
NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting);
- priv->data = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free);
priv->secrets = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, (GDestroyNotify) nm_free_secret);
}
@@ -1045,7 +1062,8 @@ finalize (GObject *object)
g_free (priv->service_type);
g_free (priv->user_name);
- g_hash_table_destroy (priv->data);
+ if (priv->data)
+ g_hash_table_unref (priv->data);
g_hash_table_destroy (priv->secrets);
G_OBJECT_CLASS (nm_setting_vpn_parent_class)->finalize (object);