shared: add nm_gobject_notify_together() helper

NM_GOBJECT_PROPERTIES_DEFINE() defines a helper function
_notify() to emit a GObject property changed notification.

Add another helper function to emit multiple notifications
together, and freeze/thaw the notification before.

This is particularly useful, because our D-Bus glue in
"nm-dbus-object.c" hooks into dispatch_properties_changed(),
to emit a combined PropertiesChanged signal for multiple
properties. By carefully freezing/thawing the notifications,
the exported objects can combine changes of multiple properties
in one D-Bus signal.

This helper is here to make that simpler.

Note that the compiler still has no problem to inline _notify()
entirey. So, in a non-debug build, there is little difference in
the generated code. It can even nicely inline calls like

    nm_gobject_notify_together (self, PROP_ADDRESS_DATA,
                                      PROP_ADDRESSES);
This commit is contained in:
Thomas Haller 2018-07-15 07:25:36 +02:00
parent d209966c29
commit ccf6bdb0e2

View file

@ -933,12 +933,36 @@ static GParamSpec *obj_properties[_PROPERTY_ENUMS_LAST] = { NULL, }
#define NM_GOBJECT_PROPERTIES_DEFINE(obj_type, ...) \
NM_GOBJECT_PROPERTIES_DEFINE_BASE (__VA_ARGS__); \
static inline void \
_nm_gobject_notify_together_impl (obj_type *obj, guint n, const _PropertyEnums *props) \
{ \
const gboolean freeze_thaw = (n > 1); \
\
nm_assert (G_IS_OBJECT (obj)); \
nm_assert (n > 0); \
\
if (freeze_thaw) \
g_object_freeze_notify ((GObject *) obj); \
while (n-- > 0) { \
const _PropertyEnums prop = *props++; \
\
nm_assert ((gsize) prop < G_N_ELEMENTS (obj_properties)); \
g_object_notify_by_pspec ((GObject *) obj, obj_properties[prop]); \
} \
if (freeze_thaw) \
g_object_thaw_notify ((GObject *) obj); \
} \
\
static inline void \
_notify (obj_type *obj, _PropertyEnums prop) \
{ \
nm_assert (G_IS_OBJECT (obj)); \
nm_assert ((gsize) prop < G_N_ELEMENTS (obj_properties)); \
g_object_notify_by_pspec ((GObject *) obj, obj_properties[prop]); \
}
_nm_gobject_notify_together_impl (obj, 1, &prop); \
} \
/* invokes _notify() for all arguments (of type _PropertyEnums). Note, that if
* there are more than one prop arguments, this will involve a freeze/thaw
* of GObject property notifications. */
#define nm_gobject_notify_together(obj, ...) \
_nm_gobject_notify_together_impl (obj, NM_NARG (__VA_ARGS__), (const _PropertyEnums[]) { __VA_ARGS__ })
/*****************************************************************************/