libnm: support direct string properties as NMRefString

Several properties like "connection.type" are enum-like and only take a few
known values. We can use a NMRefString to share their instances.

Currently nm_setting_duplicate() does not yet explicitly handle direct properties.
But it should, because it can handle them more efficiently. If it would do that, it
would be very cheap to "copy" a NMRefString. But even with the current implementation
will the result be deduplicated.
This commit is contained in:
Thomas Haller 2022-01-05 17:04:39 +01:00
parent 3b803a9d70
commit 419be57dbc
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
3 changed files with 21 additions and 2 deletions

View file

@ -9,6 +9,7 @@
#include "nm-setting.h"
#include "libnm-core-intern/nm-core-internal.h"
#include "libnm-glib-aux/nm-ref-string.h"
#include "libnm-glib-aux/nm-secret-utils.h"
#include "nm-property-compare.h"
#include "nm-setting-private.h"
@ -640,6 +641,7 @@ _property_direct_set_string(const NMSettInfoSetting *sett_info,
nm_assert(property_info->property_type->direct_type == NM_VALUE_TYPE_STRING);
nm_assert(((!!property_info->direct_set_string_ascii_strdown)
+ (!!property_info->direct_set_string_strip)
+ (!!property_info->direct_string_is_refstr)
+ (property_info->direct_set_string_mac_address_len > 0)
+ (property_info->direct_set_string_ip_address_addr_family != 0))
<= (property_info->direct_hook.set_string_fcn ? 0 : 1));
@ -650,6 +652,12 @@ _property_direct_set_string(const NMSettInfoSetting *sett_info,
dst = _nm_setting_get_private(setting, sett_info, property_info->direct_offset);
if (property_info->direct_string_is_refstr) {
nm_assert(property_info->param_spec);
nm_assert(!NM_FLAGS_HAS(property_info->param_spec->flags, NM_SETTING_PARAM_SECRET));
return nm_ref_string_reset_str_upcast((const char **) dst, src);
}
if (property_info->direct_set_string_ascii_strdown) {
s = src ? g_ascii_strdown(src, -1) : NULL;
goto out_take;
@ -1074,7 +1082,9 @@ _finalize_direct(NMSetting *setting)
char **p_val =
_nm_setting_get_private(setting, sett_info, property_info->direct_offset);
if (NM_FLAGS_HAS(property_info->param_spec->flags, NM_SETTING_PARAM_SECRET))
if (property_info->direct_string_is_refstr)
nm_clear_pointer(p_val, nm_ref_string_unref_upcast);
else if (NM_FLAGS_HAS(property_info->param_spec->flags, NM_SETTING_PARAM_SECRET))
nm_clear_pointer(p_val, nm_free_secret);
else
nm_clear_g_free(p_val);

View file

@ -4590,6 +4590,11 @@ test_setting_metadata(void)
g_assert(sip->property_type->direct_type == NM_VALUE_TYPE_STRING);
if (sip->direct_set_string_strip)
g_assert(sip->property_type->direct_type == NM_VALUE_TYPE_STRING);
if (sip->direct_string_is_refstr) {
g_assert(sip->property_type->direct_type == NM_VALUE_TYPE_STRING);
g_assert(sip->param_spec);
g_assert(!NM_FLAGS_HAS(sip->param_spec->flags, NM_SETTING_PARAM_SECRET));
}
if (sip->direct_set_string_mac_address_len != 0) {
g_assert(NM_IN_SET(sip->property_type,
@ -4604,7 +4609,8 @@ test_setting_metadata(void)
n_special_options = (sip->direct_set_string_mac_address_len != 0)
+ (!!sip->direct_set_string_strip)
+ (!!sip->direct_set_string_ascii_strdown)
+ (sip->direct_set_string_ip_address_addr_family != 0);
+ (sip->direct_set_string_ip_address_addr_family != 0)
+ (!!sip->direct_string_is_refstr);
G_STATIC_ASSERT_EXPR(AF_UNSPEC + 1 != 0);
g_assert(NM_IN_SET((int) sip->direct_set_string_ip_address_addr_family,

View file

@ -807,6 +807,9 @@ struct _NMSettInfoProperty {
* is passed to _nm_utils_ipaddr_canonical_or_invalid(). */
bool direct_set_string_ip_address_addr_family_map_zero_to_null : 1;
/* Whether the string property is implemented as a (downcast) NMRefString. */
bool direct_string_is_refstr : 1;
/* Usually, properties that are set to the default value for the GParamSpec
* are not serialized to GVariant (and NULL is returned by to_dbus_data().
* Set this flag to force always converting the property even if the value