diff options
| author | Michael Biebl <biebl@debian.org> | 2021-02-11 18:11:46 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2021-02-11 18:11:46 +0100 |
| commit | 80ec1decc49c72efec2a8b87c06245c92c0ab807 (patch) | |
| tree | e3b229aa94e8dcf0590f2317664176e7b8f7607b /src/nm-dbus-object.c | |
| parent | 65f86e8f56267192d42f2b629fc6b0c99fb9cd0c (diff) | |
New upstream version 1.29.90 upstream/1.29.90
Diffstat (limited to 'src/nm-dbus-object.c')
| -rw-r--r-- | src/nm-dbus-object.c | 332 |
1 files changed, 0 insertions, 332 deletions
diff --git a/src/nm-dbus-object.c b/src/nm-dbus-object.c deleted file mode 100644 index f49610ab..00000000 --- a/src/nm-dbus-object.c +++ /dev/null @@ -1,332 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (C) 2018 Red Hat, Inc. - */ - -#include "nm-default.h" - -#include "nm-dbus-object.h" - -#include "nm-dbus-manager.h" -#include "NetworkManagerUtils.h" - -/*****************************************************************************/ - -enum { - EXPORTED_CHANGED, - - LAST_SIGNAL, -}; - -static guint signals[LAST_SIGNAL] = {0}; - -G_DEFINE_ABSTRACT_TYPE(NMDBusObject, nm_dbus_object, G_TYPE_OBJECT); - -/*****************************************************************************/ - -#define _NMLOG_DOMAIN LOGD_CORE -#define _NMLOG(level, ...) \ - __NMLOG_DEFAULT_WITH_ADDR(level, _NMLOG_DOMAIN, "dbus-object", __VA_ARGS__) - -#define _NMLOG2_DOMAIN LOGD_DBUS_PROPS -#define _NMLOG2(level, ...) \ - __NMLOG_DEFAULT_WITH_ADDR(level, _NMLOG2_DOMAIN, "properties-changed", __VA_ARGS__) - -/*****************************************************************************/ - -static void -_emit_exported_changed(NMDBusObject *self) -{ - g_signal_emit(self, signals[EXPORTED_CHANGED], 0); -} - -static char * -_create_export_path(NMDBusObjectClass *klass) -{ - nm_assert(NM_IS_DBUS_OBJECT_CLASS(klass)); - nm_assert(klass->export_path.path); - -#if NM_MORE_ASSERTS - { - const char *p; - - p = strchr(klass->export_path.path, '%'); - if (klass->export_path.int_counter) { - nm_assert(p); - nm_assert(p[1] == 'l'); - nm_assert(p[2] == 'l'); - nm_assert(p[3] == 'u'); - nm_assert(p[4] == '\0'); - } else - nm_assert(!p); - } -#endif - - if (klass->export_path.int_counter) { - NM_PRAGMA_WARNING_DISABLE("-Wformat-nonliteral") - return g_strdup_printf(klass->export_path.path, ++(*klass->export_path.int_counter)); - NM_PRAGMA_WARNING_REENABLE - } - return g_strdup(klass->export_path.path); -} - -/** - * nm_dbus_object_export: - * @self: an #NMDBusObject - * - * Exports @self on all active and future D-Bus connections. - * - * The path to export @self on is taken from its #NMObjectClass's %export_path - * member. If the %export_path contains "%u", then it will be replaced with a - * monotonically increasing integer ID (with each distinct %export_path having - * its own counter). Otherwise, %export_path will be used literally (implying - * that @self must be a singleton). - * - * Returns: the path @self was exported under - */ -const char * -nm_dbus_object_export(gpointer /* (NMDBusObject *) */ self) -{ - NMDBusObject * self1 = self; - static guint64 id_counter = 0; - - g_return_val_if_fail(NM_IS_DBUS_OBJECT(self1), NULL); - - g_return_val_if_fail(!self1->internal.path, self1->internal.path); - - nm_assert(!self1->internal.is_unexporting); - - self1->internal.path = _create_export_path(NM_DBUS_OBJECT_GET_CLASS(self1)); - - self1->internal.export_version_id = ++id_counter; - - _LOGT("export: \"%s\"", self1->internal.path); - - _nm_dbus_manager_obj_export(self1); - - _emit_exported_changed(self1); - return self1->internal.path; -} - -/** - * nm_dbus_object_unexport: - * @self: an #NMDBusObject - * - * Unexports @self on all active D-Bus connections (and prevents it from being - * auto-exported on future connections). - */ -void -nm_dbus_object_unexport(gpointer /* (NMDBusObject *) */ self) -{ - NMDBusObject *self1 = self; - - g_return_if_fail(NM_IS_DBUS_OBJECT(self1)); - - g_return_if_fail(self1->internal.path); - - _LOGT("unexport: \"%s\"", self1->internal.path); - - /* note that we emit the signal *before* actually unexporting the object. - * The reason is, that listeners want to use this signal to know that - * the object goes away, and clear their D-Bus path to this object. - * - * But this must happen before we actually unregister the object, so - * that we first emit a D-Bus signal that other objects no longer - * reference this object, before finally unregistering the object itself. - * - * The inconvenient part is, that at this point nm_dbus_object_get_path() - * still returns the path. So, the callee needs to handle that. Possibly - * by using "nm_dbus_object_get_path_still_exported()". */ - self1->internal.is_unexporting = TRUE; - - _emit_exported_changed(self1); - - _nm_dbus_manager_obj_unexport(self1); - - nm_clear_g_free(&self1->internal.path); - self1->internal.export_version_id = 0; - - self1->internal.is_unexporting = FALSE; -} - -static gboolean -_unexport_on_idle_cb(gpointer user_data) -{ - gs_unref_object NMDBusObject *self = user_data; - - nm_dbus_object_unexport(self); - return G_SOURCE_REMOVE; -} - -void -nm_dbus_object_unexport_on_idle(gpointer /* (NMDBusObject *) */ self_take) -{ - NMDBusObject *self = g_steal_pointer(&self_take); - - if (!self) - return; - - g_return_if_fail(NM_IS_DBUS_OBJECT(self)); - - g_return_if_fail(self->internal.path); - - /* There is no mechanism to cancel or abort the unexport. It will always - * gonna happen. - * - * However, we register it to block shutdown, so that we ensure that it will happen. */ - - nm_shutdown_wait_obj_register_object(self, "unexport-dbus-obj-on-idle"); - - /* pass on ownership. */ - g_idle_add(_unexport_on_idle_cb, g_steal_pointer(&self)); -} - -/*****************************************************************************/ - -void -_nm_dbus_object_clear_and_unexport(NMDBusObject **location) -{ - NMDBusObject *self; - - g_return_if_fail(location); - if (!*location) - return; - - self = g_steal_pointer(location); - - g_return_if_fail(NM_IS_DBUS_OBJECT(self)); - - if (self->internal.path) - nm_dbus_object_unexport(self); - - g_object_unref(self); -} - -/*****************************************************************************/ - -void -nm_dbus_object_emit_signal_variant(NMDBusObject * self, - const NMDBusInterfaceInfoExtended *interface_info, - const GDBusSignalInfo * signal_info, - GVariant * args) -{ - if (!self->internal.path) { - nm_g_variant_unref_floating(args); - return; - } - _nm_dbus_manager_obj_emit_signal(self, interface_info, signal_info, args); -} - -void -nm_dbus_object_emit_signal(NMDBusObject * self, - const NMDBusInterfaceInfoExtended *interface_info, - const GDBusSignalInfo * signal_info, - const char * format, - ...) -{ - va_list ap; - - nm_assert(NM_IS_DBUS_OBJECT(self)); - nm_assert(format); - - if (!self->internal.path) - return; - - va_start(ap, format); - _nm_dbus_manager_obj_emit_signal(self, - interface_info, - signal_info, - g_variant_new_va(format, NULL, &ap)); - va_end(ap); -} - -/*****************************************************************************/ - -static void -dispatch_properties_changed(GObject *object, guint n_pspecs, GParamSpec **pspecs) -{ - NMDBusObject *self = NM_DBUS_OBJECT(object); - - if (self->internal.path) - _nm_dbus_manager_obj_notify(self, n_pspecs, (const GParamSpec *const *) pspecs); - - G_OBJECT_CLASS(nm_dbus_object_parent_class) - ->dispatch_properties_changed(object, n_pspecs, pspecs); -} - -/*****************************************************************************/ - -static void -nm_dbus_object_init(NMDBusObject *self) -{ - c_list_init(&self->internal.objects_lst); - c_list_init(&self->internal.registration_lst_head); - self->internal.bus_manager = nm_g_object_ref(nm_dbus_manager_get()); -} - -static void -constructed(GObject *object) -{ - NMDBusObjectClass *klass; - - G_OBJECT_CLASS(nm_dbus_object_parent_class)->constructed(object); - - klass = NM_DBUS_OBJECT_GET_CLASS(object); - - if (klass->export_on_construction) - nm_dbus_object_export((NMDBusObject *) object); - - /* NMDBusObject types should be very careful when overwriting notify(). - * It is possible to do, but this is a reminder that it's probably not - * a good idea. - * - * It's not a good idea, because NMDBusObject uses dispatch_properties_changed() - * to emit signals about a bunch of property changes. So, we want to make - * use of g_object_freeze_notify() / g_object_thaw_notify() to combine multiple - * property changes in one signal on D-Bus. Note that notify() is not invoked - * while the signal is frozen, that means, whatever you do inside notify() - * will not make it into the same batch of PropertiesChanged signal. That is - * confusing, and probably not what you want. - * - * Simple solution: don't overwrite notify(). */ - nm_assert(!G_OBJECT_CLASS(klass)->notify); -} - -static void -dispose(GObject *object) -{ - NMDBusObject *self = NM_DBUS_OBJECT(object); - - /* Objects should have already been unexported by their owner, unless - * we are quitting, where many objects stick around until exit. - */ - if (self->internal.path) { - if (!nm_dbus_manager_is_stopping(nm_dbus_object_get_manager(self))) - g_warn_if_reached(); - nm_dbus_object_unexport(self); - } - - G_OBJECT_CLASS(nm_dbus_object_parent_class)->dispose(object); - - g_clear_object(&self->internal.bus_manager); -} - -static void -nm_dbus_object_class_init(NMDBusObjectClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS(klass); - - object_class->constructed = constructed; - object_class->dispose = dispose; - object_class->dispatch_properties_changed = dispatch_properties_changed; - - signals[EXPORTED_CHANGED] = g_signal_new(NM_DBUS_OBJECT_EXPORTED_CHANGED, - G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); -} |