diff options
| author | Michael Biebl <biebl@debian.org> | 2021-10-01 23:05:04 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2021-10-01 23:05:04 +0200 |
| commit | e74c568b07b50b97873fb4ee1d776dedefbd54d6 (patch) | |
| tree | 3469f17ea9af91f7ff169b890633bda68b0cf76e /src/libnm-client-impl/nm-object.c | |
| parent | bfe522304da217296e2a61040f58e35ec5d6f3f2 (diff) | |
New upstream version 1.32.12 upstream/1.32.12
Diffstat (limited to 'src/libnm-client-impl/nm-object.c')
| -rw-r--r-- | src/libnm-client-impl/nm-object.c | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/src/libnm-client-impl/nm-object.c b/src/libnm-client-impl/nm-object.c new file mode 100644 index 00000000..2e7de8c2 --- /dev/null +++ b/src/libnm-client-impl/nm-object.c @@ -0,0 +1,311 @@ +/* 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, ); + +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; + + 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; + 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. + **/ + obj_properties[PROP_PATH] = g_param_spec_string(NM_OBJECT_PATH, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); +} |