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.
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
|
@@ -179,4 +179,34 @@ void nm_dbus_utils_g_value_set_object_path_from_hash (GValue *value,
|
|||||||
GHashTable *hash,
|
GHashTable *hash,
|
||||||
gboolean expect_all_exported);
|
gboolean expect_all_exported);
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
gpointer const obj;
|
||||||
|
gpointer _obj;
|
||||||
|
};
|
||||||
|
GObject *_notify_target;
|
||||||
|
const GParamSpec *_notify_pspec;
|
||||||
|
gulong _notify_signal_id;
|
||||||
|
union {
|
||||||
|
const bool visible;
|
||||||
|
bool _visible;
|
||||||
|
};
|
||||||
|
} NMDBusTrackObjPath;
|
||||||
|
|
||||||
|
void nm_dbus_track_obj_path_init (NMDBusTrackObjPath *track,
|
||||||
|
GObject *target,
|
||||||
|
const GParamSpec *pspec);
|
||||||
|
|
||||||
|
void nm_dbus_track_obj_path_deinit (NMDBusTrackObjPath *track);
|
||||||
|
|
||||||
|
void nm_dbus_track_obj_path_notify (const NMDBusTrackObjPath *track);
|
||||||
|
|
||||||
|
const char *nm_dbus_track_obj_path_get (const NMDBusTrackObjPath *track);
|
||||||
|
|
||||||
|
void nm_dbus_track_obj_path_set (NMDBusTrackObjPath *track,
|
||||||
|
gpointer obj,
|
||||||
|
gboolean visible);
|
||||||
|
|
||||||
#endif /* __NM_DBUS_UTILS_H__ */
|
#endif /* __NM_DBUS_UTILS_H__ */
|
||||||
|
Reference in New Issue
Block a user