exported-object: refactor list of interfaces from GSList to an array
NMExportedObject is the center of every D-Bus exported object in NetworkManager's core. It makes sense to optimize it. Transform the GSList of interfaces to be a array. The array is still allocated via the slice allocator (as we expect that there are only few types in the list). This saves the overhead to allocate a GSList item for each entry. Another advantage is that the interfaces list is now strongly typed instead of an opaque data pointer.
This commit is contained in:
@@ -38,13 +38,18 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMExportedObject, nm_exported_object, G_TYPE_D
|
|||||||
prefix_counters = g_hash_table_new (g_str_hash, g_str_equal);
|
prefix_counters = g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
)
|
)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GDBusInterfaceSkeleton *interface;
|
||||||
|
} InterfaceData;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NMBusManager *bus_mgr;
|
NMBusManager *bus_mgr;
|
||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
GHashTable *pending_notifies;
|
GHashTable *pending_notifies;
|
||||||
|
|
||||||
GSList *interfaces;
|
InterfaceData *interfaces;
|
||||||
|
guint num_interfaces;
|
||||||
|
|
||||||
guint notify_idle_id;
|
guint notify_idle_id;
|
||||||
|
|
||||||
@@ -148,17 +153,18 @@ nm_exported_object_signal_hook (GSignalInvocationHint *ihint,
|
|||||||
NMExportedObjectPrivate *priv;
|
NMExportedObjectPrivate *priv;
|
||||||
GSignalQuery *signal_info = data;
|
GSignalQuery *signal_info = data;
|
||||||
GDBusInterfaceSkeleton *interface = NULL;
|
GDBusInterfaceSkeleton *interface = NULL;
|
||||||
GSList *iter;
|
|
||||||
GValue *dbus_param_values;
|
GValue *dbus_param_values;
|
||||||
int i;
|
guint i;
|
||||||
|
|
||||||
priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self);
|
priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self);
|
||||||
if (!priv->path)
|
if (!priv->path)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
for (iter = priv->interfaces; iter; iter = iter->next) {
|
for (i = 0; i < priv->num_interfaces; i++) {
|
||||||
if (g_type_is_a (G_OBJECT_TYPE (iter->data), signal_info->itype)) {
|
InterfaceData *ifdata = &priv->interfaces[i];
|
||||||
interface = G_DBUS_INTERFACE_SKELETON (iter->data);
|
|
||||||
|
if (g_type_is_a (G_OBJECT_TYPE (ifdata->interface), signal_info->itype)) {
|
||||||
|
interface = ifdata->interface;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -453,9 +459,10 @@ nm_exported_object_create_skeletons (NMExportedObject *self,
|
|||||||
GObjectClass *object_class;
|
GObjectClass *object_class;
|
||||||
NMExportedObjectClassInfo *classinfo;
|
NMExportedObjectClassInfo *classinfo;
|
||||||
GSList *iter;
|
GSList *iter;
|
||||||
GDBusInterfaceSkeleton *interface;
|
|
||||||
const NMExportedObjectDBusMethodImpl *methods;
|
const NMExportedObjectDBusMethodImpl *methods;
|
||||||
guint methods_len;
|
guint i, methods_len;
|
||||||
|
guint num_interfaces;
|
||||||
|
InterfaceData *interfaces;
|
||||||
|
|
||||||
classinfo = g_type_get_qdata (object_type, nm_exported_object_class_info_quark ());
|
classinfo = g_type_get_qdata (object_type, nm_exported_object_class_info_quark ());
|
||||||
if (!classinfo)
|
if (!classinfo)
|
||||||
@@ -467,17 +474,30 @@ nm_exported_object_create_skeletons (NMExportedObject *self,
|
|||||||
methods = classinfo->methods->len ? &g_array_index (classinfo->methods, NMExportedObjectDBusMethodImpl, 0) : NULL;
|
methods = classinfo->methods->len ? &g_array_index (classinfo->methods, NMExportedObjectDBusMethodImpl, 0) : NULL;
|
||||||
methods_len = classinfo->methods->len;
|
methods_len = classinfo->methods->len;
|
||||||
|
|
||||||
for (iter = classinfo->skeleton_types; iter; iter = iter->next) {
|
num_interfaces = g_slist_length (classinfo->skeleton_types);
|
||||||
interface = nm_exported_object_skeleton_create (GPOINTER_TO_SIZE (iter->data),
|
g_return_if_fail (num_interfaces > 0);
|
||||||
|
|
||||||
|
interfaces = g_slice_alloc (sizeof (InterfaceData) * (num_interfaces + priv->num_interfaces));
|
||||||
|
|
||||||
|
for (i = num_interfaces, iter = classinfo->skeleton_types; iter; iter = iter->next) {
|
||||||
|
InterfaceData *ifdata = &interfaces[--i];
|
||||||
|
|
||||||
|
ifdata->interface = nm_exported_object_skeleton_create (GPOINTER_TO_SIZE (iter->data),
|
||||||
object_class,
|
object_class,
|
||||||
methods,
|
methods,
|
||||||
methods_len,
|
methods_len,
|
||||||
(GObject *) self);
|
(GObject *) self);
|
||||||
|
g_dbus_object_skeleton_add_interface ((GDBusObjectSkeleton *) self, ifdata->interface);
|
||||||
g_dbus_object_skeleton_add_interface ((GDBusObjectSkeleton *) self, interface);
|
|
||||||
|
|
||||||
priv->interfaces = g_slist_prepend (priv->interfaces, interface);
|
|
||||||
}
|
}
|
||||||
|
nm_assert (i == 0);
|
||||||
|
|
||||||
|
if (priv->num_interfaces > 0) {
|
||||||
|
memcpy (&interfaces[num_interfaces], priv->interfaces, sizeof (InterfaceData) * priv->num_interfaces);
|
||||||
|
g_slice_free1 (sizeof (InterfaceData) * priv->num_interfaces, priv->interfaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->num_interfaces = num_interfaces + priv->num_interfaces;
|
||||||
|
priv->interfaces = interfaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -506,16 +526,22 @@ static void
|
|||||||
nm_exported_object_destroy_skeletons (NMExportedObject *self)
|
nm_exported_object_destroy_skeletons (NMExportedObject *self)
|
||||||
{
|
{
|
||||||
NMExportedObjectPrivate *priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self);
|
NMExportedObjectPrivate *priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self);
|
||||||
|
guint n;
|
||||||
|
|
||||||
g_return_if_fail (priv->interfaces);
|
g_return_if_fail (priv->num_interfaces > 0);
|
||||||
|
nm_assert (priv->interfaces);
|
||||||
|
|
||||||
while (priv->interfaces) {
|
n = priv->num_interfaces;
|
||||||
GDBusInterfaceSkeleton *interface = priv->interfaces->data;
|
|
||||||
|
|
||||||
priv->interfaces = g_slist_delete_link (priv->interfaces, priv->interfaces);
|
while (priv->num_interfaces > 0) {
|
||||||
g_dbus_object_skeleton_remove_interface ((GDBusObjectSkeleton *) self, interface);
|
InterfaceData *ifdata = &priv->interfaces[--priv->num_interfaces];
|
||||||
nm_exported_object_skeleton_release (interface);
|
|
||||||
|
g_dbus_object_skeleton_remove_interface ((GDBusObjectSkeleton *) self, ifdata->interface);
|
||||||
|
nm_exported_object_skeleton_release (ifdata->interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_slice_free1 (sizeof (InterfaceData) * n, priv->interfaces);
|
||||||
|
priv->interfaces = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -664,30 +690,26 @@ nm_exported_object_unexport (NMExportedObject *self)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GSList *
|
GDBusInterfaceSkeleton *
|
||||||
nm_exported_object_get_interfaces (NMExportedObject *self)
|
nm_exported_object_get_interface_by_type (NMExportedObject *self, GType interface_type)
|
||||||
{
|
{
|
||||||
NMExportedObjectPrivate *priv;
|
NMExportedObjectPrivate *priv;
|
||||||
|
guint i;
|
||||||
|
|
||||||
g_return_val_if_fail (NM_IS_EXPORTED_OBJECT (self), NULL);
|
g_return_val_if_fail (NM_IS_EXPORTED_OBJECT (self), NULL);
|
||||||
|
|
||||||
priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self);
|
priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self);
|
||||||
|
|
||||||
g_return_val_if_fail (priv->path, NULL);
|
g_return_val_if_fail (priv->path, NULL);
|
||||||
g_return_val_if_fail (priv->interfaces, NULL);
|
g_return_val_if_fail (priv->num_interfaces > 0, NULL);
|
||||||
|
|
||||||
return priv->interfaces;
|
nm_assert (priv->interfaces);
|
||||||
}
|
|
||||||
|
|
||||||
GDBusInterfaceSkeleton *
|
for (i = 0; i < priv->num_interfaces; i++) {
|
||||||
nm_exported_object_get_interface_by_type (NMExportedObject *self, GType interface_type)
|
InterfaceData *ifdata = &priv->interfaces[i];
|
||||||
{
|
|
||||||
GSList *interfaces;
|
|
||||||
|
|
||||||
interfaces = nm_exported_object_get_interfaces (self);
|
if (G_TYPE_CHECK_INSTANCE_TYPE (ifdata->interface, interface_type))
|
||||||
for (; interfaces; interfaces = interfaces->next) {
|
return ifdata->interface;
|
||||||
if (G_TYPE_CHECK_INSTANCE_TYPE (interfaces->data, interface_type))
|
|
||||||
return interfaces->data;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -742,7 +764,6 @@ idle_emit_properties_changed (gpointer self)
|
|||||||
{
|
{
|
||||||
NMExportedObjectPrivate *priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self);
|
NMExportedObjectPrivate *priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self);
|
||||||
gs_unref_variant GVariant *variant = NULL;
|
gs_unref_variant GVariant *variant = NULL;
|
||||||
GSList *iter;
|
|
||||||
GDBusInterfaceSkeleton *interface = NULL;
|
GDBusInterfaceSkeleton *interface = NULL;
|
||||||
guint signal_id = 0;
|
guint signal_id = 0;
|
||||||
GHashTableIter hash_iter;
|
GHashTableIter hash_iter;
|
||||||
@@ -773,10 +794,12 @@ idle_emit_properties_changed (gpointer self)
|
|||||||
|
|
||||||
g_hash_table_remove_all (priv->pending_notifies);
|
g_hash_table_remove_all (priv->pending_notifies);
|
||||||
|
|
||||||
for (iter = priv->interfaces; iter; iter = iter->next) {
|
for (i = 0; i < priv->num_interfaces; i++) {
|
||||||
signal_id = g_signal_lookup ("properties-changed", G_OBJECT_TYPE (iter->data));
|
InterfaceData *ifdata = &priv->interfaces[i];
|
||||||
|
|
||||||
|
signal_id = g_signal_lookup ("properties-changed", G_OBJECT_TYPE (ifdata->interface));
|
||||||
if (signal_id != 0) {
|
if (signal_id != 0) {
|
||||||
interface = G_DBUS_INTERFACE_SKELETON (iter->data);
|
interface = ifdata->interface;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -819,9 +842,9 @@ nm_exported_object_notify (GObject *object, GParamSpec *pspec)
|
|||||||
GValue value = G_VALUE_INIT;
|
GValue value = G_VALUE_INIT;
|
||||||
const GVariantType *vtype;
|
const GVariantType *vtype;
|
||||||
GVariant *variant;
|
GVariant *variant;
|
||||||
GSList *iter;
|
guint i;
|
||||||
|
|
||||||
if (!priv->interfaces)
|
if (priv->num_interfaces == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (type = G_OBJECT_TYPE (object); type; type = g_type_parent (type)) {
|
for (type = G_OBJECT_TYPE (object); type; type = g_type_parent (type)) {
|
||||||
@@ -843,8 +866,8 @@ nm_exported_object_notify (GObject *object, GParamSpec *pspec)
|
|||||||
g_object_get_property (G_OBJECT (object), pspec->name, &value);
|
g_object_get_property (G_OBJECT (object), pspec->name, &value);
|
||||||
|
|
||||||
vtype = NULL;
|
vtype = NULL;
|
||||||
for (iter = priv->interfaces; iter && !vtype; iter = iter->next)
|
for (i = 0; !vtype && i < priv->num_interfaces; i++)
|
||||||
vtype = find_dbus_property_type (iter->data, dbus_property_name);
|
vtype = find_dbus_property_type (priv->interfaces[i].interface, dbus_property_name);
|
||||||
g_return_if_fail (vtype != NULL);
|
g_return_if_fail (vtype != NULL);
|
||||||
|
|
||||||
variant = g_dbus_gvalue_to_gvariant (&value, vtype);
|
variant = g_dbus_gvalue_to_gvariant (&value, vtype);
|
||||||
|
@@ -74,7 +74,6 @@ const char *nm_exported_object_export (NMExportedObject *self);
|
|||||||
const char *nm_exported_object_get_path (NMExportedObject *self);
|
const char *nm_exported_object_get_path (NMExportedObject *self);
|
||||||
gboolean nm_exported_object_is_exported (NMExportedObject *self);
|
gboolean nm_exported_object_is_exported (NMExportedObject *self);
|
||||||
void nm_exported_object_unexport (NMExportedObject *self);
|
void nm_exported_object_unexport (NMExportedObject *self);
|
||||||
GSList * nm_exported_object_get_interfaces (NMExportedObject *self);
|
|
||||||
GDBusInterfaceSkeleton *nm_exported_object_get_interface_by_type (NMExportedObject *self, GType interface_type);
|
GDBusInterfaceSkeleton *nm_exported_object_get_interface_by_type (NMExportedObject *self, GType interface_type);
|
||||||
|
|
||||||
void _nm_exported_object_clear_and_unexport (NMExportedObject **location);
|
void _nm_exported_object_clear_and_unexport (NMExportedObject **location);
|
||||||
|
Reference in New Issue
Block a user