mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-25 07:10:07 +01:00
We use clang-format for automatic formatting of our source files. Since clang-format is actively maintained software, the actual formatting depends on the used version of clang-format. That is unfortunate and painful, but really unavoidable unless clang-format would be strictly bug-compatible. So the version that we must use is from the current Fedora release, which is also tested by our gitlab-ci. Previously, we were using Fedora 34 with clang-tools-extra-12.0.1-1.fc34.x86_64. As Fedora 35 comes along, we need to update our formatting as Fedora 35 comes with version "13.0.0~rc1-1.fc35". An alternative would be to freeze on version 12, but that has different problems (like, it's cumbersome to rebuild clang 12 on Fedora 35 and it would be cumbersome for our developers which are on Fedora 35 to use a clang that they cannot easily install). The (differently painful) solution is to reformat from time to time, as we switch to a new Fedora (and thus clang) version. Usually we would expect that such a reformatting brings minor changes. But this time, the changes are huge. That is mentioned in the release notes [1] as Makes PointerAligment: Right working with AlignConsecutiveDeclarations. (Fixes https://llvm.org/PR27353) [1] https://releases.llvm.org/13.0.0/tools/clang/docs/ReleaseNotes.html#clang-format
338 lines
9.8 KiB
C
338 lines
9.8 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
/*
|
|
* Copyright (C) 2007 - 2008 Novell, Inc.
|
|
* Copyright (C) 2007 - 2012 Red Hat, Inc.
|
|
*/
|
|
|
|
#include "libnm-client-impl/nm-default-libnm.h"
|
|
|
|
#include "nm-object.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
#include "nm-utils.h"
|
|
#include "nm-dbus-interface.h"
|
|
#include "nm-object-private.h"
|
|
#include "nm-dbus-helpers.h"
|
|
#include "nm-client.h"
|
|
#include "libnm-core-intern/nm-core-internal.h"
|
|
#include "c-list/src/c-list.h"
|
|
|
|
/*****************************************************************************/
|
|
|
|
NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PATH, PROP_CLIENT, );
|
|
|
|
typedef struct _NMObjectPrivate {
|
|
NMClient *client;
|
|
NMLDBusObject *dbobj;
|
|
} NMObjectPrivate;
|
|
|
|
G_DEFINE_ABSTRACT_TYPE(NMObject, nm_object, G_TYPE_OBJECT);
|
|
|
|
#define NM_OBJECT_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMObject, NM_IS_OBJECT)
|
|
|
|
static NMObjectClass *_nm_object_class = NULL;
|
|
|
|
/*****************************************************************************/
|
|
|
|
static gpointer
|
|
_nm_object_get_private(NMObjectClass *klass, NMObject *self, guint16 extra_offset)
|
|
{
|
|
char *ptr;
|
|
|
|
nm_assert(klass->priv_ptr_offset > 0);
|
|
|
|
ptr = (char *) self;
|
|
ptr += klass->priv_ptr_offset;
|
|
if (klass->priv_ptr_indirect)
|
|
ptr = *((gpointer *) ptr);
|
|
return ptr + extra_offset;
|
|
}
|
|
|
|
NMLDBusObject *
|
|
_nm_object_get_dbobj(gpointer self)
|
|
{
|
|
return NM_OBJECT_GET_PRIVATE(self)->dbobj;
|
|
}
|
|
|
|
const char *
|
|
_nm_object_get_path(gpointer self)
|
|
{
|
|
return NM_OBJECT_GET_PRIVATE(self)->dbobj->dbus_path->str;
|
|
}
|
|
|
|
NMClient *
|
|
_nm_object_get_client(gpointer self)
|
|
{
|
|
return NM_OBJECT_GET_PRIVATE(self)->client;
|
|
}
|
|
|
|
/**
|
|
* nm_object_get_path:
|
|
* @object: a #NMObject
|
|
*
|
|
* Gets the DBus path of the #NMObject.
|
|
*
|
|
* Returns: the object's path. This is the internal string used by the
|
|
* object, and must not be modified.
|
|
*
|
|
* Note that the D-Bus path of an NMObject never changes, even
|
|
* if the instance gets removed from the cache. To find out
|
|
* whether the object is still alive/cached, check nm_object_get_client().
|
|
**/
|
|
const char *
|
|
nm_object_get_path(NMObject *object)
|
|
{
|
|
g_return_val_if_fail(NM_IS_OBJECT(object), NULL);
|
|
|
|
return _nm_object_get_path(object);
|
|
}
|
|
|
|
/**
|
|
* nm_object_get_client:
|
|
* @object: a #NMObject
|
|
*
|
|
* Returns the #NMClient instance in which object is cached.
|
|
* Also, if the object got removed from the client cached,
|
|
* this returns %NULL. So it can be used to check whether the
|
|
* object is still alive.
|
|
*
|
|
* Returns: (transfer none): the #NMClient cache in which the
|
|
* object can be found, or %NULL if the object is no longer
|
|
* cached.
|
|
*
|
|
* Since: 1.24
|
|
**/
|
|
NMClient *
|
|
nm_object_get_client(NMObject *object)
|
|
{
|
|
g_return_val_if_fail(NM_IS_OBJECT(object), NULL);
|
|
|
|
return _nm_object_get_client(object);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
static void
|
|
clear_properties(NMObject *self, NMClient *client)
|
|
{
|
|
NMObjectClass *klass = NM_OBJECT_GET_CLASS(self);
|
|
const _NMObjectClassFieldInfo *p;
|
|
|
|
nm_assert(NM_IS_OBJECT(self));
|
|
nm_assert(!client || NM_IS_CLIENT(client));
|
|
|
|
for (p = klass->property_o_info; p; p = p->parent) {
|
|
nml_dbus_property_o_clear_many(_nm_object_get_private(p->klass, self, p->offset),
|
|
p->num,
|
|
client);
|
|
}
|
|
|
|
for (p = klass->property_ao_info; p; p = p->parent) {
|
|
nml_dbus_property_ao_clear_many(_nm_object_get_private(p->klass, self, p->offset),
|
|
p->num,
|
|
client);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
static gboolean
|
|
is_ready(NMObject *self)
|
|
{
|
|
NMObjectClass *klass = NM_OBJECT_GET_CLASS(self);
|
|
NMClient *client = _nm_object_get_client(self);
|
|
const _NMObjectClassFieldInfo *p;
|
|
guint16 i;
|
|
|
|
nm_assert(NM_IS_CLIENT(client));
|
|
|
|
for (p = klass->property_o_info; p; p = p->parent) {
|
|
NMLDBusPropertyO *fields = _nm_object_get_private(p->klass, self, p->offset);
|
|
|
|
for (i = 0; i < p->num; i++) {
|
|
if (!nml_dbus_property_o_is_ready(&fields[i]))
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
for (p = klass->property_ao_info; p; p = p->parent) {
|
|
NMLDBusPropertyAO *fields = _nm_object_get_private(p->klass, self, p->offset);
|
|
|
|
for (i = 0; i < p->num; i++) {
|
|
if (!nml_dbus_property_ao_is_ready(&fields[i]))
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
obj_changed_notify(NMObject *self)
|
|
{
|
|
NMObjectClass *klass = NM_OBJECT_GET_CLASS(self);
|
|
NMClient *client = _nm_object_get_client(self);
|
|
const _NMObjectClassFieldInfo *p;
|
|
|
|
nm_assert(NM_IS_CLIENT(client));
|
|
|
|
for (p = klass->property_o_info; p; p = p->parent) {
|
|
nml_dbus_property_o_notify_changed_many(_nm_object_get_private(p->klass, self, p->offset),
|
|
p->num,
|
|
client);
|
|
}
|
|
|
|
for (p = klass->property_ao_info; p; p = p->parent) {
|
|
nml_dbus_property_ao_notify_changed_many(_nm_object_get_private(p->klass, self, p->offset),
|
|
p->num,
|
|
client);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
static void
|
|
register_client(NMObject *self, NMClient *client, NMLDBusObject *dbobj)
|
|
{
|
|
NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE(self);
|
|
|
|
nm_assert(!priv->client);
|
|
nm_assert(NML_IS_DBUS_OBJECT(dbobj));
|
|
nm_assert(dbobj->nmobj == G_OBJECT(self));
|
|
|
|
priv->client = client;
|
|
priv->dbobj = nml_dbus_object_ref(dbobj);
|
|
}
|
|
|
|
static void
|
|
unregister_client(NMObject *self, NMClient *client, NMLDBusObject *dbobj)
|
|
{
|
|
NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE(self);
|
|
|
|
nm_assert(NM_IS_CLIENT(client));
|
|
nm_assert(priv->client == client);
|
|
priv->client = NULL;
|
|
|
|
_nm_client_queue_notify_object(client, self, obj_properties[PROP_CLIENT]);
|
|
|
|
clear_properties(self, client);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
static void
|
|
get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
|
{
|
|
NMObject *self = NM_OBJECT(object);
|
|
|
|
switch (prop_id) {
|
|
case PROP_PATH:
|
|
g_value_set_string(value, nm_object_get_path(self));
|
|
break;
|
|
case PROP_CLIENT:
|
|
g_value_set_object(value, nm_object_get_client(self));
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
static void
|
|
nm_object_init(NMObject *object)
|
|
{
|
|
NMObject *self = NM_OBJECT(object);
|
|
NMObjectPrivate *priv;
|
|
|
|
priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_OBJECT, NMObjectPrivate);
|
|
|
|
self->_priv = priv;
|
|
|
|
c_list_init(&self->obj_base.queue_notify_lst);
|
|
|
|
NML_DBUS_LOG(_NML_NMCLIENT_LOG_LEVEL_COERCE(NML_DBUS_LOG_LEVEL_TRACE),
|
|
"nmobj[" NM_HASH_OBFUSCATE_PTR_FMT "]: creating",
|
|
NM_HASH_OBFUSCATE_PTR(self));
|
|
}
|
|
|
|
static void
|
|
dispose(GObject *object)
|
|
{
|
|
NMObject *self = NM_OBJECT(object);
|
|
NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE(self);
|
|
|
|
if (!self->obj_base.is_disposing) {
|
|
NML_DBUS_LOG(_NML_NMCLIENT_LOG_LEVEL_COERCE(NML_DBUS_LOG_LEVEL_TRACE),
|
|
"nmobj[" NM_HASH_OBFUSCATE_PTR_FMT "]: disposing",
|
|
NM_HASH_OBFUSCATE_PTR(self));
|
|
}
|
|
|
|
self->obj_base.is_disposing = TRUE;
|
|
|
|
nm_assert(c_list_is_empty(&self->obj_base.queue_notify_lst));
|
|
nm_assert(!priv->client);
|
|
nm_assert(!priv->dbobj || !priv->dbobj->nmobj);
|
|
|
|
clear_properties(self, NULL);
|
|
|
|
G_OBJECT_CLASS(nm_object_parent_class)->dispose(object);
|
|
|
|
nm_clear_pointer(&priv->dbobj, nml_dbus_object_unref);
|
|
}
|
|
|
|
static void
|
|
nm_object_class_init(NMObjectClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
|
|
|
_nm_object_class = klass;
|
|
|
|
g_type_class_add_private(klass, sizeof(NMObjectPrivate));
|
|
|
|
object_class->get_property = get_property;
|
|
object_class->dispose = dispose;
|
|
|
|
klass->register_client = register_client;
|
|
klass->unregister_client = unregister_client;
|
|
klass->is_ready = is_ready;
|
|
klass->obj_changed_notify = obj_changed_notify;
|
|
|
|
/**
|
|
* NMObject:path:
|
|
*
|
|
* The D-Bus object path.
|
|
*
|
|
* The D-Bus path of an object instance never changes, even if the object
|
|
* gets removed from the cache. To see whether the object is still in the
|
|
* cache, check NMObject:client.
|
|
**/
|
|
obj_properties[PROP_PATH] = g_param_spec_string(NM_OBJECT_PATH,
|
|
"",
|
|
"",
|
|
NULL,
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
|
|
|
/**
|
|
* NMObject:client:
|
|
*
|
|
* The NMClient instance as returned by nm_object_get_client().
|
|
*
|
|
* When an NMObject gets removed from the NMClient cache,
|
|
* the NMObject:path property stays unchanged, but this client
|
|
* instance gets reset to %NULL. You can use this property to
|
|
* track removal of the object from the cache.
|
|
*
|
|
* Since: 1.34
|
|
**/
|
|
obj_properties[PROP_CLIENT] = g_param_spec_object(NM_OBJECT_CLIENT,
|
|
"",
|
|
"",
|
|
NM_TYPE_CLIENT,
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
|
|
|
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
|
}
|