diff options
author | Thomas Haller <thaller@redhat.com> | 2021-06-17 22:10:48 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2021-06-23 12:47:31 +0200 |
commit | a832781a8a64c96cd8bca8b2e591a1fd2b3bad8e (patch) | |
tree | 2e978010e515c8ddbfa890f915334541b7ab195f | |
parent | 54cab39ac99fc6d5ad7378a93bcdb6dc8c340330 (diff) |
libnm: extend to_dbus_fcn() property type for efficiently converting boolean property
Most of our NMSetting properties are based around GObject properties,
and thus the tooling to convert a NMSetting to/from GVariant consists
of getting/setting a GValue.
We can do better.
For most of such properties we also define a C getter function, which
we can call with less overhead. All we need is to hook the C getter with
the property meta data.
As example, implement it for "connection.autoconnect".
The immediate goal of this is to reduce the overhead of to_dbus. But
note that also for comparison of two properties, there is the default
implementation which is used by the majority of properties. This
implementation converts the properties first to GVariant (via
to_dbus_fcn) and then compares the variants. What this commit also does,
is to hook up the property meta data with the C-getters. This is one step
towards also more efficiently compare properties using the naive C
getters. Likewise, the keyfile writer use g_object_get_property().
It also could do better.
-rw-r--r-- | src/libnm-core-impl/nm-setting-connection.c | 13 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting-private.h | 73 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting.c | 23 | ||||
-rw-r--r-- | src/libnm-core-impl/tests/test-setting.c | 5 | ||||
-rw-r--r-- | src/libnm-core-intern/nm-core-internal.h | 1 |
5 files changed, 108 insertions, 7 deletions
diff --git a/src/libnm-core-impl/nm-setting-connection.c b/src/libnm-core-impl/nm-setting-connection.c index cc38982bca..81f280be9e 100644 --- a/src/libnm-core-impl/nm-setting-connection.c +++ b/src/libnm-core-impl/nm-setting-connection.c @@ -2079,12 +2079,13 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) * description: Whether the connection should be autoconnected (not only while booting). * ---end--- */ - obj_properties[PROP_AUTOCONNECT] = g_param_spec_boolean( - NM_SETTING_CONNECTION_AUTOCONNECT, - "", - "", - TRUE, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + _nm_setting_property_define_boolean(properties_override, + obj_properties, + NM_SETTING_CONNECTION_AUTOCONNECT, + PROP_AUTOCONNECT, + TRUE, + NM_SETTING_PARAM_FUZZY_IGNORE, + nm_setting_connection_get_autoconnect); /** * NMSettingConnection:autoconnect-priority: diff --git a/src/libnm-core-impl/nm-setting-private.h b/src/libnm-core-impl/nm-setting-private.h index cca1ac37e0..93c2f03623 100644 --- a/src/libnm-core-impl/nm-setting-private.h +++ b/src/libnm-core-impl/nm-setting-private.h @@ -253,6 +253,8 @@ extern const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_ignore_u extern const NMSettInfoPropertType nm_sett_info_propert_type_plain_i; extern const NMSettInfoPropertType nm_sett_info_propert_type_plain_u; +extern const NMSettInfoPropertType nm_sett_info_propert_type_boolean; + NMSettingVerifyResult _nm_setting_verify(NMSetting *setting, NMConnection *connection, GError **error); @@ -272,6 +274,14 @@ GVariant *_nm_setting_property_to_dbus_fcn_gprop(const NMSettInfoSetting * NMConnectionSerializationFlags flags, const NMConnectionSerializationOptions *options); +GVariant * +_nm_setting_property_to_dbus_fcn_get_boolean(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options); + GVariant *_nm_setting_to_dbus(NMSetting * setting, NMConnection * connection, NMConnectionSerializationFlags flags, @@ -376,6 +386,69 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p /*****************************************************************************/ +#define _nm_setting_property_define_boolean_full(properties_override, \ + obj_properties, \ + prop_name, \ + prop_id, \ + default_value, \ + param_flags, \ + property_type, \ + get_fcn, \ + ...) \ + G_STMT_START \ + { \ + const gboolean _default_value = (default_value); \ + GParamSpec * _param_spec; \ + const NMSettInfoPropertType *const _property_type = (property_type); \ + \ + G_STATIC_ASSERT( \ + !NM_FLAGS_ANY((param_flags), \ + ~(NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_INFERRABLE \ + | NM_SETTING_PARAM_REAPPLY_IMMEDIATELY))); \ + \ + nm_assert(_property_type); \ + nm_assert(_property_type->to_dbus_fcn == _nm_setting_property_to_dbus_fcn_get_boolean); \ + \ + nm_assert(NM_IN_SET(_default_value, 0, 1)); \ + \ + _param_spec = \ + g_param_spec_boolean("" prop_name "", \ + "", \ + "", \ + _default_value, \ + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \ + \ + (obj_properties)[(prop_id)] = _param_spec; \ + \ + _nm_properties_override_gobj((properties_override), \ + _param_spec, \ + _property_type, \ + .to_dbus_data.get_boolean = \ + (gboolean(*)(NMSetting *)) (get_fcn), \ + __VA_ARGS__); \ + } \ + G_STMT_END + +#define _nm_setting_property_define_boolean(properties_override, \ + obj_properties, \ + prop_name, \ + prop_id, \ + default_value, \ + param_flags, \ + get_fcn, \ + ...) \ + _nm_setting_property_define_boolean_full((properties_override), \ + (obj_properties), \ + prop_name, \ + (prop_id), \ + (default_value), \ + (param_flags), \ + &nm_sett_info_propert_type_boolean, \ + (get_fcn), \ + __VA_ARGS__) + +/*****************************************************************************/ + gboolean _nm_setting_use_legacy_property(NMSetting * setting, GVariant * connection_dict, const char *legacy_property, diff --git a/src/libnm-core-impl/nm-setting.c b/src/libnm-core-impl/nm-setting.c index 5fbb66dbac..261c32d4a9 100644 --- a/src/libnm-core-impl/nm-setting.c +++ b/src/libnm-core-impl/nm-setting.c @@ -176,7 +176,7 @@ _nm_properties_override_assert(const NMSettInfoProperty *prop_info) if (!prop_info->param_spec) { /* if we don't have a param_spec, we cannot have gprop_from_dbus_fcn. */ - nm_assert(!property_type->gprop_from_dbus_fcn); + nm_assert(property_type->from_dbus_fcn || !property_type->gprop_from_dbus_fcn); } } #endif @@ -532,6 +532,23 @@ _nm_setting_use_legacy_property(NMSetting * setting, /*****************************************************************************/ GVariant * +_nm_setting_property_to_dbus_fcn_get_boolean(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + const NMSettInfoProperty *property_info = &sett_info->property_infos[property_idx]; + gboolean val; + + val = !!property_info->to_dbus_data.get_boolean(setting); + if (val == NM_G_PARAM_SPEC_GET_DEFAULT_BOOLEAN(property_info->param_spec)) + return NULL; + return g_variant_ref(nm_g_variant_singleton_b(val)); +} + +GVariant * _nm_setting_property_to_dbus_fcn_gprop(const NMSettInfoSetting * sett_info, guint property_idx, NMConnection * connection, @@ -2356,6 +2373,10 @@ const NMSettInfoPropertType nm_sett_info_propert_type_plain_i = const NMSettInfoPropertType nm_sett_info_propert_type_plain_u = NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT(G_VARIANT_TYPE_UINT32); +const NMSettInfoPropertType nm_sett_info_propert_type_boolean = NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT( + G_VARIANT_TYPE_BOOLEAN, + .to_dbus_fcn = _nm_setting_property_to_dbus_fcn_get_boolean); + /*****************************************************************************/ static GenData * diff --git a/src/libnm-core-impl/tests/test-setting.c b/src/libnm-core-impl/tests/test-setting.c index 6a342bcca8..0572de1412 100644 --- a/src/libnm-core-impl/tests/test-setting.c +++ b/src/libnm-core-impl/tests/test-setting.c @@ -4402,6 +4402,11 @@ check_done:; if (sip->property_type->typdata_to_dbus.gprop_type != NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_DEFAULT) g_assert(!sip->to_dbus_data.gprop_to_dbus_fcn); + } else if (sip->property_type->to_dbus_fcn + == _nm_setting_property_to_dbus_fcn_get_boolean) { + g_assert(sip->param_spec); + g_assert(sip->param_spec->value_type == G_TYPE_BOOLEAN); + g_assert(sip->to_dbus_data.get_boolean); } g_assert(!sip->property_type->from_dbus_fcn diff --git a/src/libnm-core-intern/nm-core-internal.h b/src/libnm-core-intern/nm-core-internal.h index 657c66d683..1fde5d455d 100644 --- a/src/libnm-core-intern/nm-core-internal.h +++ b/src/libnm-core-intern/nm-core-internal.h @@ -711,6 +711,7 @@ struct _NMSettInfoProperty { union { gpointer none; NMSettInfoPropGPropToDBusFcn gprop_to_dbus_fcn; + gboolean (*get_boolean)(NMSetting *); }; } to_dbus_data; }; |