diff --git a/configure.ac b/configure.ac index 6311c37364..4efc71b094 100644 --- a/configure.ac +++ b/configure.ac @@ -273,13 +273,11 @@ AC_SEARCH_LIBS([dlopen], [dl dld], [test "$ac_cv_search_dlopen" = "none required" || AC_SUBST([DL_LIBS], "$ac_cv_search_dlopen"]), []) -PKG_CHECK_MODULES(GLIB, [gio-unix-2.0 >= 2.37.6 gmodule-2.0], - [AC_SUBST(LOG_DRIVER, '$(top_srcdir)/build-aux/tap-driver.sh') - AC_SUBST(AM_TESTS_FD_REDIRECT, '--tap')], - [PKG_CHECK_MODULES(GLIB, gio-unix-2.0 >= 2.40 gmodule-2.0) - AC_SUBST(LOG_DRIVER, '$(top_srcdir)/build-aux/test-driver')]) +PKG_CHECK_MODULES(GLIB, [gio-unix-2.0 >= 2.42 gmodule-2.0]) -GLIB_CFLAGS="$GLIB_CFLAGS -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_40 -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_40" +AC_SUBST(LOG_DRIVER, '$(top_srcdir)/build-aux/test-driver') + +GLIB_CFLAGS="$GLIB_CFLAGS -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_42 -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_42" AC_SUBST(GLIB_CFLAGS) AC_SUBST(GLIB_LIBS) diff --git a/meson.build b/meson.build index 87012698b6..ab8a9fd78d 100644 --- a/meson.build +++ b/meson.build @@ -274,7 +274,7 @@ config_h.set10('HAVE_LIBSYSTEMD', libsystemd_dep.found()) systemd_dep = dependency('systemd', required: false) -gio_unix_dep = dependency('gio-unix-2.0', version: '>= 2.40') +gio_unix_dep = dependency('gio-unix-2.0', version: '>= 2.42') glib_dep = declare_dependency( dependencies: [ @@ -282,8 +282,8 @@ glib_dep = declare_dependency( dependency('gmodule-2.0'), ], compile_args: [ - '-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_40', - '-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_40', + '-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_42', + '-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_42', ] ) diff --git a/src/core/devices/nm-device-wireguard.c b/src/core/devices/nm-device-wireguard.c index df84e77bad..dd40d11e47 100644 --- a/src/core/devices/nm-device-wireguard.c +++ b/src/core/devices/nm-device-wireguard.c @@ -598,7 +598,7 @@ _peers_add(NMDeviceWireGuard *self, NMWireGuardPeer *peer) }; c_list_link_tail(&priv->lst_peers_head, &peer_data->lst_peers); - if (!nm_g_hash_table_add(priv->peers, peer_data)) + if (!g_hash_table_add(priv->peers, peer_data)) nm_assert_not_reached(); return peer_data; } diff --git a/src/libnm-core-impl/nm-setting-ip-config.c b/src/libnm-core-impl/nm-setting-ip-config.c index ed6cdf90ef..3bbad42544 100644 --- a/src/libnm-core-impl/nm-setting-ip-config.c +++ b/src/libnm-core-impl/nm-setting-ip-config.c @@ -6437,7 +6437,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) G_MININT32, G_MAXINT32, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:addresses: (type GPtrArray(NMIPAddress)) @@ -6535,14 +6535,15 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) * * Since: 1.10 **/ - obj_properties[PROP_ROUTE_TABLE] = g_param_spec_uint( - NM_SETTING_IP_CONFIG_ROUTE_TABLE, - "", - "", - 0, - G_MAXUINT32, - 0, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ROUTE_TABLE] = + g_param_spec_uint(NM_SETTING_IP_CONFIG_ROUTE_TABLE, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY + | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:ignore-auto-routes: * @@ -6555,7 +6556,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", "", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:ignore-auto-dns: @@ -6571,7 +6572,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", "", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:dhcp-hostname: @@ -6602,7 +6603,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", "", TRUE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:never-default: @@ -6616,7 +6617,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", "", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:may-fail: @@ -6634,7 +6635,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", "", TRUE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:dad-timeout: @@ -6652,14 +6653,15 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) * * Since: 1.2 **/ - obj_properties[PROP_DAD_TIMEOUT] = g_param_spec_int( - NM_SETTING_IP_CONFIG_DAD_TIMEOUT, - "", - "", - -1, - NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, - -1, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_DAD_TIMEOUT] = + g_param_spec_int(NM_SETTING_IP_CONFIG_DAD_TIMEOUT, + "", + "", + -1, + NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, + -1, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:dhcp-timeout: @@ -6670,14 +6672,15 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) * * Set to 2147483647 (MAXINT32) for infinity. **/ - obj_properties[PROP_DHCP_TIMEOUT] = g_param_spec_int( - NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, - "", - "", - 0, - G_MAXINT32, - 0, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_DHCP_TIMEOUT] = + g_param_spec_int(NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, + "", + "", + 0, + G_MAXINT32, + 0, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:required-timeout: @@ -6702,14 +6705,15 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) * * Since: 1.34 **/ - obj_properties[PROP_REQUIRED_TIMEOUT] = g_param_spec_int( - NM_SETTING_IP_CONFIG_REQUIRED_TIMEOUT, - "", - "", - -1, - G_MAXINT32, - -1, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_REQUIRED_TIMEOUT] = + g_param_spec_int(NM_SETTING_IP_CONFIG_REQUIRED_TIMEOUT, + "", + "", + -1, + G_MAXINT32, + -1, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:dhcp-iaid: @@ -6778,7 +6782,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) 0, G_MAXUINT32, NM_DHCP_HOSTNAME_FLAG_NONE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:dhcp-reject-servers: diff --git a/src/libnm-core-impl/nm-setting-ip6-config.c b/src/libnm-core-impl/nm-setting-ip6-config.c index 272523b143..82715e2637 100644 --- a/src/libnm-core-impl/nm-setting-ip6-config.c +++ b/src/libnm-core-impl/nm-setting-ip6-config.c @@ -1181,7 +1181,7 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) NM_SETTING_PARAM_NONE, NMSettingIP6ConfigPrivate, dhcp_pd_hint, - .direct_hook.set_string_fcn = + .direct_set_fcn.set_string = _set_string_fcn_dhcp_pd_hint); /* IP6-specific property overrides */ diff --git a/src/libnm-core-impl/nm-setting-ovs-port.c b/src/libnm-core-impl/nm-setting-ovs-port.c index 190f1e5d6c..f15cf2de4b 100644 --- a/src/libnm-core-impl/nm-setting-ovs-port.c +++ b/src/libnm-core-impl/nm-setting-ovs-port.c @@ -349,7 +349,7 @@ verify_trunks(GPtrArray *ranges, GError **error) } for (vlan = range->start; vlan <= range->end; vlan++) { - if (!nm_g_hash_table_add(h, GUINT_TO_POINTER(vlan))) { + if (!g_hash_table_add(h, GUINT_TO_POINTER(vlan))) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, diff --git a/src/libnm-core-impl/nm-setting-private.h b/src/libnm-core-impl/nm-setting-private.h index 943348fb72..f31796a664 100644 --- a/src/libnm-core-impl/nm-setting-private.h +++ b/src/libnm-core-impl/nm-setting-private.h @@ -475,20 +475,20 @@ void _nm_setting_class_commit(NMSettingClass *setting_class, gboolean _nm_properties_override_assert(const NMSettInfoProperty *prop_info); -static inline void +static inline guint _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *prop_info) { nm_assert(properties_override); nm_assert(_nm_properties_override_assert(prop_info)); g_array_append_vals(properties_override, prop_info, 1); + return properties_override->len - 1u; } #define _nm_properties_override_gobj(properties_override, \ p_param_spec, \ p_property_type, \ ... /* extra NMSettInfoProperty fields */) \ - G_STMT_START \ - { \ + ({ \ GParamSpec *const _p_param_spec_2 = (p_param_spec); \ \ nm_assert(_p_param_spec_2); \ @@ -498,8 +498,7 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p .param_spec = _p_param_spec_2, \ .property_type = (p_property_type), \ __VA_ARGS__)); \ - } \ - G_STMT_END + }) #define _nm_properties_override_dbus(properties_override, \ p_name, \ @@ -543,12 +542,12 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p \ 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)); \ + _param_spec = g_param_spec_boolean("" prop_name "", \ + "", \ + "", \ + _default_value, \ + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY \ + | G_PARAM_STATIC_STRINGS | (param_flags)); \ \ (obj_properties)[(prop_id)] = _param_spec; \ \ @@ -586,14 +585,14 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p G_STATIC_ASSERT((default_value) <= (guint64) (max_value)); \ G_STATIC_ASSERT((max_value) <= (guint64) G_MAXUINT32); \ \ - _param_spec = \ - g_param_spec_uint("" prop_name "", \ - "", \ - "", \ - (min_value), \ - (max_value), \ - (default_value), \ - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \ + _param_spec = g_param_spec_uint("" prop_name "", \ + "", \ + "", \ + (min_value), \ + (max_value), \ + (default_value), \ + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY \ + | G_PARAM_STATIC_STRINGS | (param_flags)); \ \ (obj_properties)[(prop_id)] = _param_spec; \ \ @@ -632,14 +631,14 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p G_STATIC_ASSERT((default_value) <= (gint64) (max_value)); \ G_STATIC_ASSERT((max_value) <= (gint64) G_MAXUINT32); \ \ - _param_spec = \ - g_param_spec_int("" prop_name "", \ - "", \ - "", \ - (min_value), \ - (max_value), \ - (default_value), \ - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \ + _param_spec = g_param_spec_int("" prop_name "", \ + "", \ + "", \ + (min_value), \ + (max_value), \ + (default_value), \ + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY \ + | G_PARAM_STATIC_STRINGS | (param_flags)); \ \ (obj_properties)[(prop_id)] = _param_spec; \ \ @@ -755,8 +754,7 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p private_struct_type, \ private_struct_field, \ ... /* extra NMSettInfoProperty fields */) \ - G_STMT_START \ - { \ + ({ \ GParamSpec *_param_spec; \ const NMSettInfoPropertType *_property_type = (property_type); \ \ @@ -786,8 +784,7 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p .direct_offset = \ NM_STRUCT_OFFSET_ENSURE_TYPE(char *, private_struct_type, private_struct_field), \ __VA_ARGS__); \ - } \ - G_STMT_END + }) #define _nm_setting_property_define_direct_string(properties_override, \ obj_properties, \ diff --git a/src/libnm-core-impl/nm-setting-wireguard.c b/src/libnm-core-impl/nm-setting-wireguard.c index b0e3f66cbf..f736a54496 100644 --- a/src/libnm-core-impl/nm-setting-wireguard.c +++ b/src/libnm-core-impl/nm-setting-wireguard.c @@ -1318,7 +1318,7 @@ _peers_set(NMSettingWireGuardPrivate *priv, }; g_ptr_array_add(priv->peers_arr, pd_same_key); - if (!nm_g_hash_table_add(priv->peers_hash, pd_same_key)) + if (!g_hash_table_add(priv->peers_hash, pd_same_key)) nm_assert_not_reached(); nm_assert(_peers_get(priv, pd_same_key->idx) == pd_same_key); @@ -2362,7 +2362,7 @@ nm_setting_wireguard_class_init(NMSettingWireGuardClass *klass) NM_SETTING_PARAM_SECRET, NMSettingWireGuard, _priv.private_key, - .direct_hook.set_string_fcn = + .direct_set_fcn.set_string = _set_string_fcn_public_key); /** diff --git a/src/libnm-core-impl/nm-setting.c b/src/libnm-core-impl/nm-setting.c index f3399d58c8..4999e46baf 100644 --- a/src/libnm-core-impl/nm-setting.c +++ b/src/libnm-core-impl/nm-setting.c @@ -683,10 +683,10 @@ _property_direct_set_string(const NMSettInfoSetting *sett_info, + (!!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)); + <= (property_info->direct_set_fcn.set_string ? 0 : 1)); - if (property_info->direct_hook.set_string_fcn) { - return property_info->direct_hook.set_string_fcn(sett_info, property_info, setting, src); + if (property_info->direct_set_fcn.set_string) { + return property_info->direct_set_fcn.set_string(sett_info, property_info, setting, src); } dst = _nm_setting_get_private_field(setting, sett_info, property_info); @@ -989,10 +989,11 @@ _nm_setting_property_set_property_direct(GObject *object, nm_assert_not_reached(); out_notify: - /* If explicit-notify would be set, we would need to emit g_object_notify_by_pspec(). - * - * Currently we never set that, also because we still support glib 2.40. */ - nm_assert(!NM_FLAGS_HAS(pspec->flags, 1 << 30 /* G_PARAM_EXPLICIT_NOTIFY */)); + nm_gobject_notify_together_by_pspec( + object, + NM_FLAGS_HAS(pspec->flags, G_PARAM_EXPLICIT_NOTIFY) ? property_info->param_spec : NULL, + property_info->direct_also_notify); + return; out_fail: @@ -1388,7 +1389,9 @@ _nm_setting_property_from_dbus_fcn_direct_mac_address(_NM_SETT_INFO_PROP_FROM_DB if (nm_strdup_reset_take(_nm_setting_get_private_field(setting, sett_info, property_info), length > 0 ? nm_utils_hwaddr_ntoa(array, length) : NULL)) { - g_object_notify_by_pspec(G_OBJECT(setting), property_info->param_spec); + nm_gobject_notify_together_by_pspec(setting, + property_info->param_spec, + property_info->direct_also_notify); } else *out_is_modified = FALSE; @@ -1692,7 +1695,9 @@ out_unchanged: out_notify: *out_is_modified = TRUE; - g_object_notify_by_pspec(G_OBJECT(setting), property_info->param_spec); + nm_gobject_notify_together_by_pspec(setting, + property_info->param_spec, + property_info->direct_also_notify); return TRUE; out_error_wrong_dbus_type: diff --git a/src/libnm-core-impl/nm-utils.c b/src/libnm-core-impl/nm-utils.c index 61b931868a..4cc7464aee 100644 --- a/src/libnm-core-impl/nm-utils.c +++ b/src/libnm-core-impl/nm-utils.c @@ -5534,7 +5534,7 @@ _nm_utils_bridge_vlan_verify_list(GPtrArray *vlans, nm_bridge_vlan_get_vid_range(vlan, &vid_start, &vid_end); for (v = vid_start; v <= vid_end; v++) { - if (!nm_g_hash_table_add(h, GUINT_TO_POINTER(v))) { + if (!g_hash_table_add(h, GUINT_TO_POINTER(v))) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, diff --git a/src/libnm-core-impl/tests/test-setting.c b/src/libnm-core-impl/tests/test-setting.c index e9aa99819f..1a1df172a6 100644 --- a/src/libnm-core-impl/tests/test-setting.c +++ b/src/libnm-core-impl/tests/test-setting.c @@ -4565,7 +4565,7 @@ test_setting_metadata(void) GArray *property_types_data; guint prop_idx_val; gboolean can_set_including_default = FALSE; - gboolean can_have_direct_hook = FALSE; + gboolean can_have_direct_set_fcn = FALSE; int n_special_options; g_assert(sip->name); @@ -4708,7 +4708,7 @@ test_setting_metadata(void) g_assert(g_variant_type_equal(sip->property_type->dbus_type, "s")); g_assert(sip->property_type->to_dbus_fcn == _nm_setting_property_to_dbus_fcn_direct); - can_have_direct_hook = TRUE; + can_have_direct_set_fcn = TRUE; } g_assert(sip->param_spec); g_assert(sip->param_spec->value_type == G_TYPE_STRING); @@ -4746,8 +4746,26 @@ test_setting_metadata(void) g_assert(sip->property_type->direct_type == NM_VALUE_TYPE_STRING); } - if (!can_have_direct_hook) - g_assert(!sip->direct_hook.set_string_fcn); + if (!can_have_direct_set_fcn) + g_assert(!sip->direct_set_fcn.set_string); + + if (sip->property_type->direct_type == NM_VALUE_TYPE_NONE) + g_assert(!sip->direct_also_notify); + else { + if (sip->direct_also_notify) { + guint prop_idx2; + guint cnt = 0; + + for (prop_idx2 = 0; prop_idx2 < sis->property_infos_len; prop_idx2++) { + const NMSettInfoProperty *sip2 = &sis->property_infos[prop_idx2]; + + if (sip2->param_spec == sip->direct_also_notify) + cnt++; + } + g_assert_cmpint(cnt, ==, 1u); + g_assert(sip->param_spec != sip->direct_also_notify); + } + } n_special_options = (sip->direct_set_string_mac_address_len != 0) + (!!sip->direct_set_string_strip) @@ -4884,6 +4902,29 @@ check_done:; prop_idx_val = _PROP_IDX_PACK(meta_type, prop_idx); g_array_append_val(property_types_data, prop_idx_val); + if (sip->param_spec) { + gboolean expected; + + /* TODO: we should move all "direct" properties to use G_PARAM_EXPLICIT_NOTIFY. + * + * Currently only certain direct properties are as such. This should change. + * + * Warning: this is potentially dangerous, because implementations MUST remember + * to notify the property change in set_property(). Optimally, the property uses + * _nm_setting_property_set_property_direct(), which takes care of that. + */ + expected = NM_IN_SET(sip->property_type->direct_type, + NM_VALUE_TYPE_BOOL, + NM_VALUE_TYPE_UINT32, + NM_VALUE_TYPE_INT32); + + if (NM_FLAGS_HAS(sip->param_spec->flags, G_PARAM_EXPLICIT_NOTIFY)) { + g_assert(expected); + } else { + g_assert(!expected); + } + } + if (sip->param_spec) { nm_auto_unset_gvalue GValue val = G_VALUE_INIT; diff --git a/src/libnm-core-intern/nm-core-internal.h b/src/libnm-core-intern/nm-core-internal.h index 2172ed0b9c..efc2613a21 100644 --- a/src/libnm-core-intern/nm-core-internal.h +++ b/src/libnm-core-intern/nm-core-internal.h @@ -778,11 +778,15 @@ struct _NMSettInfoProperty { union { /* Optional hook for direct string properties, this gets called when setting the string. * Return whether the value changed. */ - gboolean (*set_string_fcn)(const NMSettInfoSetting *sett_info, - const NMSettInfoProperty *property_info, - NMSetting *setting, - const char *src); - } direct_hook; + gboolean (*set_string)(const NMSettInfoSetting *sett_info, + const NMSettInfoProperty *property_info, + NMSetting *setting, + const char *src); + } direct_set_fcn; + + /* For direct properties, this is the param_spec that also should be + * notified on changes. */ + GParamSpec *direct_also_notify; /* This only has meaning for direct properties (property_type->direct_type != NM_VALUE_TYPE_UNSPEC). * In that case, this is the offset where _nm_setting_get_private() can find diff --git a/src/libnm-glib-aux/nm-glib.h b/src/libnm-glib-aux/nm-glib.h index 8d1208cf08..cf76cf1311 100644 --- a/src/libnm-glib-aux/nm-glib.h +++ b/src/libnm-glib-aux/nm-glib.h @@ -29,22 +29,6 @@ /*****************************************************************************/ -static inline void -__g_type_ensure(GType type) -{ -#if !GLIB_CHECK_VERSION(2, 34, 0) - if (G_UNLIKELY(type == (GType) -1)) - g_error("can't happen"); -#else - G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - g_type_ensure(type); - G_GNUC_END_IGNORE_DEPRECATIONS; -#endif -} -#define g_type_ensure __g_type_ensure - -/*****************************************************************************/ - /* glib 2.58+ defines an improved, type-safe variant of g_clear_pointer(). Reimplement * that. * @@ -81,71 +65,6 @@ __g_type_ensure(GType type) /*****************************************************************************/ -#if !GLIB_CHECK_VERSION(2, 34, 0) - -/* These are used to clean up the output of test programs; we can just let - * them no-op in older glib. - */ -#define g_test_expect_message(log_domain, log_level, pattern) -#define g_test_assert_expected_messages() - -#else - -/* We build with -DGLIB_MAX_ALLOWED_VERSION set to 2.32 to make sure we don't - * accidentally use new API that we shouldn't. But we don't want warnings for - * the APIs that we emulate above. - */ - -#define g_test_expect_message(domain, level, format...) \ - G_STMT_START \ - { \ - G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ - g_test_expect_message(domain, level, format); \ - G_GNUC_END_IGNORE_DEPRECATIONS \ - } \ - G_STMT_END - -#define g_test_assert_expected_messages_internal(domain, file, line, func) \ - G_STMT_START \ - { \ - G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ - g_test_assert_expected_messages_internal(domain, file, line, func); \ - G_GNUC_END_IGNORE_DEPRECATIONS \ - } \ - G_STMT_END - -#endif - -/*****************************************************************************/ - -#if GLIB_CHECK_VERSION(2, 35, 0) -/* For glib >= 2.36, g_type_init() is deprecated. - * But since 2.35.1 (7c42ab23b55c43ab96d0ac2124b550bf1f49c1ec) this function - * does nothing. Replace the call with empty statement. */ -#define nm_g_type_init() \ - G_STMT_START \ - { \ - (void) 0; \ - } \ - G_STMT_END -#else -#define nm_g_type_init() \ - G_STMT_START \ - { \ - g_type_init(); \ - } \ - G_STMT_END -#endif - -/*****************************************************************************/ - -/* g_test_initialized() is only available since glib 2.36. */ -#if !GLIB_CHECK_VERSION(2, 36, 0) -#define g_test_initialized() (g_test_config_vars->test_initialized) -#endif - -/*****************************************************************************/ - /* g_assert_cmpmem() is only available since glib 2.46. */ #if !GLIB_CHECK_VERSION(2, 45, 7) #define g_assert_cmpmem(m1, l1, m2, l2) \ @@ -189,136 +108,6 @@ nm_glib_check_version(guint major, guint minor, guint micro) /*****************************************************************************/ -/* g_test_skip() is only available since glib 2.38. Add a compatibility wrapper. */ -static inline void -__nmtst_g_test_skip(const char *msg) -{ -#if GLIB_CHECK_VERSION(2, 38, 0) - G_GNUC_BEGIN_IGNORE_DEPRECATIONS - g_test_skip(msg); - G_GNUC_END_IGNORE_DEPRECATIONS -#else - g_debug("%s", msg); -#endif -} -#define g_test_skip __nmtst_g_test_skip - -/*****************************************************************************/ - -/* g_test_add_data_func_full() is only available since glib 2.34. Add a compatibility wrapper. */ -static inline void -__g_test_add_data_func_full(const char *testpath, - gpointer test_data, - GTestDataFunc test_func, - GDestroyNotify data_free_func) -{ -#if GLIB_CHECK_VERSION(2, 34, 0) - G_GNUC_BEGIN_IGNORE_DEPRECATIONS - g_test_add_data_func_full(testpath, test_data, test_func, data_free_func); - G_GNUC_END_IGNORE_DEPRECATIONS -#else - g_return_if_fail(testpath != NULL); - g_return_if_fail(testpath[0] == '/'); - g_return_if_fail(test_func != NULL); - - g_test_add_vtable(testpath, - 0, - test_data, - NULL, - (GTestFixtureFunc) test_func, - (GTestFixtureFunc) data_free_func); -#endif -} -#define g_test_add_data_func_full __g_test_add_data_func_full - -/*****************************************************************************/ - -static inline gboolean -nm_g_hash_table_replace(GHashTable *hash, gpointer key, gpointer value) -{ - /* glib 2.40 added a return value indicating whether the key already existed - * (910191597a6c2e5d5d460e9ce9efb4f47d9cc63c). */ -#if GLIB_CHECK_VERSION(2, 40, 0) - return g_hash_table_replace(hash, key, value); -#else - gboolean contained = g_hash_table_contains(hash, key); - - g_hash_table_replace(hash, key, value); - return !contained; -#endif -} - -static inline gboolean -nm_g_hash_table_insert(GHashTable *hash, gpointer key, gpointer value) -{ - /* glib 2.40 added a return value indicating whether the key already existed - * (910191597a6c2e5d5d460e9ce9efb4f47d9cc63c). */ -#if GLIB_CHECK_VERSION(2, 40, 0) - return g_hash_table_insert(hash, key, value); -#else - gboolean contained = g_hash_table_contains(hash, key); - - g_hash_table_insert(hash, key, value); - return !contained; -#endif -} - -static inline gboolean -nm_g_hash_table_add(GHashTable *hash, gpointer key) -{ - /* glib 2.40 added a return value indicating whether the key already existed - * (910191597a6c2e5d5d460e9ce9efb4f47d9cc63c). */ -#if GLIB_CHECK_VERSION(2, 40, 0) - return g_hash_table_add(hash, key); -#else - gboolean contained = g_hash_table_contains(hash, key); - - g_hash_table_add(hash, key); - return !contained; -#endif -} - -/*****************************************************************************/ - -#if !GLIB_CHECK_VERSION(2, 40, 0) || defined(NM_GLIB_COMPAT_H_TEST) -static inline void -_nm_g_ptr_array_insert(GPtrArray *array, int index_, gpointer data) -{ - g_return_if_fail(array); - g_return_if_fail(index_ >= -1); - g_return_if_fail(index_ <= (int) array->len); - - g_ptr_array_add(array, data); - - if (index_ != -1 && index_ != (int) (array->len - 1)) { - memmove(&(array->pdata[index_ + 1]), - &(array->pdata[index_]), - (array->len - index_ - 1) * sizeof(gpointer)); - array->pdata[index_] = data; - } -} -#endif - -#if !GLIB_CHECK_VERSION(2, 40, 0) -#define g_ptr_array_insert(array, index, data) \ - G_STMT_START \ - { \ - _nm_g_ptr_array_insert(array, index, data); \ - } \ - G_STMT_END -#else -#define g_ptr_array_insert(array, index, data) \ - G_STMT_START \ - { \ - G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ - g_ptr_array_insert(array, index, data); \ - G_GNUC_END_IGNORE_DEPRECATIONS \ - } \ - G_STMT_END -#endif - -/*****************************************************************************/ - #if !GLIB_CHECK_VERSION(2, 54, 0) static inline gboolean g_ptr_array_find(GPtrArray *haystack, gconstpointer needle, guint *index_) @@ -346,106 +135,6 @@ g_ptr_array_find(GPtrArray *haystack, gconstpointer needle, guint *index_) /*****************************************************************************/ -#if !GLIB_CHECK_VERSION(2, 40, 0) -static inline gboolean -_g_key_file_save_to_file(GKeyFile *key_file, const char *filename, GError **error) -{ - char *contents; - gboolean success; - gsize length; - - g_return_val_if_fail(key_file != NULL, FALSE); - g_return_val_if_fail(filename != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - contents = g_key_file_to_data(key_file, &length, NULL); - g_assert(contents != NULL); - - success = g_file_set_contents(filename, contents, length, error); - g_free(contents); - - return success; -} -#define g_key_file_save_to_file(key_file, filename, error) \ - _g_key_file_save_to_file(key_file, filename, error) -#else -#define g_key_file_save_to_file(key_file, filename, error) \ - ({ \ - gboolean _success; \ - \ - G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ - _success = g_key_file_save_to_file(key_file, filename, error); \ - G_GNUC_END_IGNORE_DEPRECATIONS \ - _success; \ - }) -#endif - -/*****************************************************************************/ - -#if GLIB_CHECK_VERSION(2, 36, 0) -#define g_credentials_get_unix_pid(creds, error) \ - ({ \ - G_GNUC_BEGIN_IGNORE_DEPRECATIONS(g_credentials_get_unix_pid)((creds), (error)); \ - G_GNUC_END_IGNORE_DEPRECATIONS \ - }) -#else -#define g_credentials_get_unix_pid(creds, error) \ - ({ \ - struct ucred *native_creds; \ - \ - native_creds = g_credentials_get_native((creds), G_CREDENTIALS_TYPE_LINUX_UCRED); \ - g_assert(native_creds); \ - native_creds->pid; \ - }) -#endif - -/*****************************************************************************/ - -#if !GLIB_CHECK_VERSION(2, 40, 0) || defined(NM_GLIB_COMPAT_H_TEST) -static inline gpointer * -_nm_g_hash_table_get_keys_as_array(GHashTable *hash_table, guint *length) -{ - GHashTableIter iter; - gpointer key, *ret; - guint i = 0; - - g_return_val_if_fail(hash_table, NULL); - - ret = g_new0(gpointer, g_hash_table_size(hash_table) + 1); - g_hash_table_iter_init(&iter, hash_table); - - while (g_hash_table_iter_next(&iter, &key, NULL)) - ret[i++] = key; - - ret[i] = NULL; - - if (length) - *length = i; - - return ret; -} -#endif -#if !GLIB_CHECK_VERSION(2, 40, 0) -#define g_hash_table_get_keys_as_array(hash_table, length) \ - ({ _nm_g_hash_table_get_keys_as_array(hash_table, length); }) -#else -#define g_hash_table_get_keys_as_array(hash_table, length) \ - ({ \ - G_GNUC_BEGIN_IGNORE_DEPRECATIONS(g_hash_table_get_keys_as_array) \ - ((hash_table), (length)); \ - G_GNUC_END_IGNORE_DEPRECATIONS \ - }) -#endif - -/*****************************************************************************/ - -#ifndef g_info -/* g_info was only added with 2.39.2 */ -#define g_info(...) g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, __VA_ARGS__) -#endif - -/*****************************************************************************/ - #ifdef g_steal_pointer #undef g_steal_pointer #endif @@ -486,69 +175,6 @@ _nm_g_strv_contains(const char *const *strv, const char *str) /*****************************************************************************/ -static inline GVariant * -_nm_g_variant_new_take_string(char *string) -{ -#if !GLIB_CHECK_VERSION(2, 36, 0) - GVariant *value; - - g_return_val_if_fail(string != NULL, NULL); - g_return_val_if_fail(g_utf8_validate(string, -1, NULL), NULL); - - value = g_variant_new_string(string); - g_free(string); - return value; -#elif !GLIB_CHECK_VERSION(2, 38, 0) - GVariant *value; - GBytes *bytes; - - g_return_val_if_fail(string != NULL, NULL); - g_return_val_if_fail(g_utf8_validate(string, -1, NULL), NULL); - - bytes = g_bytes_new_take(string, strlen(string) + 1); - value = g_variant_new_from_bytes(G_VARIANT_TYPE_STRING, bytes, TRUE); - g_bytes_unref(bytes); - - return value; -#else - G_GNUC_BEGIN_IGNORE_DEPRECATIONS - return g_variant_new_take_string(string); - G_GNUC_END_IGNORE_DEPRECATIONS -#endif -} -#define g_variant_new_take_string _nm_g_variant_new_take_string - -/*****************************************************************************/ - -#if !GLIB_CHECK_VERSION(2, 38, 0) -_nm_printf(1, 2) static inline GVariant *_nm_g_variant_new_printf(const char *format_string, ...) -{ - char *string; - va_list ap; - - g_return_val_if_fail(format_string, NULL); - - va_start(ap, format_string); - string = g_strdup_vprintf(format_string, ap); - va_end(ap); - - return g_variant_new_take_string(string); -} -#define g_variant_new_printf(...) _nm_g_variant_new_printf(__VA_ARGS__) -#else -#define g_variant_new_printf(...) \ - ({ \ - GVariant *_v; \ - \ - G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ - _v = g_variant_new_printf(__VA_ARGS__); \ - G_GNUC_END_IGNORE_DEPRECATIONS \ - _v; \ - }) -#endif - -/*****************************************************************************/ - /* Recent glib also casts the results to typeof(Obj), but only if * * ( defined(g_has_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_56 ) diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c index 7db45e1b90..6cbfea2c8a 100644 --- a/src/libnm-glib-aux/nm-shared-utils.c +++ b/src/libnm-glib-aux/nm-shared-utils.c @@ -2217,6 +2217,44 @@ nm_utils_error_is_notfound(GError *error) /*****************************************************************************/ +void +nm_gobject_notify_together_by_pspec_v(gpointer obj, + const GParamSpec *const *param_specs, + gsize param_specs_len) +{ + GObject *const gobj = obj; + gboolean frozen = FALSE; + const GParamSpec *pspec_first = NULL; + + nm_assert(G_IS_OBJECT(gobj)); + nm_assert(param_specs_len > 0); + + while (param_specs_len-- > 0) { + const GParamSpec *pspec = (param_specs++)[0]; + + if (!pspec) + continue; + + if (!frozen) { + if (!pspec_first) { + pspec_first = pspec; + continue; + } + frozen = TRUE; + g_object_freeze_notify(gobj); + g_object_notify_by_pspec(gobj, (GParamSpec *) pspec_first); + } + g_object_notify_by_pspec(gobj, (GParamSpec *) pspec); + } + + if (frozen) + g_object_thaw_notify(gobj); + else if (pspec_first) + g_object_notify_by_pspec(gobj, (GParamSpec *) pspec_first); +} + +/*****************************************************************************/ + /** * nm_g_object_set_property: * @object: the target object diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h index 4288e164e2..b0ce25a568 100644 --- a/src/libnm-glib-aux/nm-shared-utils.h +++ b/src/libnm-glib-aux/nm-shared-utils.h @@ -1115,6 +1115,21 @@ nm_utils_error_set_literal(GError **error, int error_code, const char *literal) /*****************************************************************************/ +void nm_gobject_notify_together_by_pspec_v(gpointer obj, + const GParamSpec *const *param_specs, + gsize param_specs_len); + +#define nm_gobject_notify_together_by_pspec(obj, ...) \ + G_STMT_START \ + { \ + const GParamSpec *const _arr[] = {__VA_ARGS__}; \ + \ + G_STATIC_ASSERT(NM_NARG(__VA_ARGS__) == G_N_ELEMENTS(_arr)); \ + \ + nm_gobject_notify_together_by_pspec_v((obj), _arr, G_N_ELEMENTS(_arr)); \ + } \ + G_STMT_END + gboolean nm_g_object_set_property(GObject *object, const char *property_name, const GValue *value, diff --git a/src/libnm-glib-aux/nm-test-utils.h b/src/libnm-glib-aux/nm-test-utils.h index ec3a246657..34b83beeef 100644 --- a/src/libnm-glib-aux/nm-test-utils.h +++ b/src/libnm-glib-aux/nm-test-utils.h @@ -497,8 +497,6 @@ __nmtst_init(int *argc, __nmtst_internal.assert_logging = !!assert_logging; - nm_g_type_init(); - is_debug = g_test_verbose(); nmtst_debug = g_getenv("NMTST_DEBUG"); @@ -2605,7 +2603,7 @@ _nmtst_assert_connection_has_settings(NMConnection *connection, va_start(ap, has_at_most); while ((name = va_arg(ap, const char *))) { - if (!nm_g_hash_table_add(names, (gpointer) name)) + if (!g_hash_table_add(names, (gpointer) name)) g_assert_not_reached(); g_ptr_array_add(names_arr, (gpointer) name); }