diff options
author | Thomas Haller <thaller@redhat.com> | 2018-04-03 16:37:20 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2018-04-13 09:09:46 +0200 |
commit | 86229a669bc3c51faf19f15c6a382c20f849b78e (patch) | |
tree | 395e904ee1d0271cc3690be13ca8dbbc6727700a /src/nm-dbus-utils.c | |
parent | 4127f1234fc4593cb80ad01435ac2b1743c8d5e2 (diff) | |
download | NetworkManager-86229a669bc3c51faf19f15c6a382c20f849b78e.tar.gz |
core: add NMDBusTrackObjPath helper
When one D-Bus object exposes (the path of) another D-Bus object,
we want that the path property gets cleared before the other
object gets unexported(). That essentially requires to register
to the "exported-changed" signal.
Add a helper struct NMDBusTrackObjPath to help with this.
Diffstat (limited to 'src/nm-dbus-utils.c')
-rw-r--r-- | src/nm-dbus-utils.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/nm-dbus-utils.c b/src/nm-dbus-utils.c index b79cc34371..5a57206c76 100644 --- a/src/nm-dbus-utils.c +++ b/src/nm-dbus-utils.c @@ -207,3 +207,102 @@ nm_dbus_utils_get_paths_for_clist (const CList *lst_head, } /*****************************************************************************/ + +void +nm_dbus_track_obj_path_init (NMDBusTrackObjPath *track, + GObject *target, + const GParamSpec *pspec) +{ + nm_assert (track); + nm_assert (G_IS_OBJECT (target)); + nm_assert (G_IS_PARAM_SPEC (pspec)); + + track->_obj = NULL; + track->_notify_target = target; + track->_notify_pspec = pspec; + track->_notify_signal_id = 0; + track->_visible = FALSE; +} + +void +nm_dbus_track_obj_path_deinit (NMDBusTrackObjPath *track) +{ + /* we allow deinit() to be called multiple times (e.g. from + * dispose(), which must be re-entrant). */ + nm_assert (track); + nm_assert (!track->_notify_target || G_IS_OBJECT (track->_notify_target)); + + nm_clear_g_signal_handler (track->obj, &track->_notify_signal_id); + track->_notify_target = NULL; + track->_notify_pspec = NULL; + track->_visible = FALSE; + nm_clear_g_object (&track->_obj); +} + +void +nm_dbus_track_obj_path_notify (const NMDBusTrackObjPath *track) +{ + nm_assert (track); + nm_assert (G_IS_OBJECT (track->_notify_target)); + nm_assert (G_IS_PARAM_SPEC (track->_notify_pspec)); + + g_object_notify_by_pspec (track->_notify_target, + (GParamSpec *) track->_notify_pspec); +} + +const char * +nm_dbus_track_obj_path_get (const NMDBusTrackObjPath *track) +{ + nm_assert (track); + nm_assert (G_IS_OBJECT (track->_notify_target)); + + return track->obj && track->visible + ? nm_dbus_object_get_path_still_exported (track->obj) + : NULL; +} + +static void +_track_obj_exported_changed (NMDBusObject *obj, + NMDBusTrackObjPath *track) +{ + nm_dbus_track_obj_path_notify (track); +} + +void +nm_dbus_track_obj_path_set (NMDBusTrackObjPath *track, + gpointer obj, + gboolean visible) +{ + gs_unref_object NMDBusObject *old_obj = NULL; + const char *old_path; + + nm_assert (track); + nm_assert (G_IS_OBJECT (track->_notify_target)); + + g_return_if_fail (!obj || NM_IS_DBUS_OBJECT (obj)); + + if ( track->obj == obj + && track->visible == !!visible) + return; + + old_path = nm_dbus_track_obj_path_get (track); + + track->_visible = visible; + + if (track->obj != obj) { + nm_clear_g_signal_handler (track->obj, &track->_notify_signal_id); + + old_obj = track->obj; + track->_obj = nm_g_object_ref (obj); + + if (obj) { + track->_notify_signal_id = g_signal_connect (obj, + NM_DBUS_OBJECT_EXPORTED_CHANGED, + G_CALLBACK (_track_obj_exported_changed), + track); + } + } + + if (!nm_streq0 (old_path, nm_dbus_track_obj_path_get (track))) + nm_dbus_track_obj_path_notify (track); +} |