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,
|
||||
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__ */
|
||||
|
Reference in New Issue
Block a user