summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-11-20 15:31:59 +0100
committerThomas Haller <thaller@redhat.com>2018-12-04 13:15:17 +0100
commitaffdbeb44de06f3eb1099f2593b3a2edca8f7dc1 (patch)
tree94ca85aff91e367a2e4e78293ae19e3a72d08397
parent6aba07572814d49e9ca5233d2b4a5edfa33aee2e (diff)
downloadNetworkManager-affdbeb44de06f3eb1099f2593b3a2edca8f7dc1.tar.gz
keep-alive: let NMKeepAlive instance access the owner object that it is keeping alive
NMKeepAlive is a full API independent of NMActiveConnection. For good reasons: - it moves complexity away from nm-active-connection.c - in the future, we can use NMKeepAlive also for NMSettingsConnection As such, the user should also directly interact with NMKeepAlive, instead of going through NMActiveConnection. For that to work, it must be possible to get the owner of the NMKeepAlive instance, which is kept alive.
-rw-r--r--src/nm-active-connection.c3
-rw-r--r--src/nm-keep-alive.c60
-rw-r--r--src/nm-keep-alive.h6
3 files changed, 69 insertions, 0 deletions
diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c
index 59f7622c77..559d05cf13 100644
--- a/src/nm-active-connection.c
+++ b/src/nm-active-connection.c
@@ -1447,6 +1447,7 @@ nm_active_connection_init (NMActiveConnection *self)
priv->version_id = _version_id_new ();
priv->keep_alive = nm_keep_alive_new ();
+ _nm_keep_alive_set_owner (priv->keep_alive, G_OBJECT (self));
g_signal_connect_object (priv->keep_alive, "notify::" NM_KEEP_ALIVE_ALIVE,
(GCallback) keep_alive_alive_changed,
self,
@@ -1532,6 +1533,8 @@ finalize (GObject *object)
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
nm_dbus_track_obj_path_set (&priv->settings_connection, NULL, FALSE);
+
+ _nm_keep_alive_set_owner (priv->keep_alive, NULL);
g_clear_object (&priv->keep_alive);
G_OBJECT_CLASS (nm_active_connection_parent_class)->finalize (object);
diff --git a/src/nm-keep-alive.c b/src/nm-keep-alive.c
index 0b3b7fabd7..4af6c38ddb 100644
--- a/src/nm-keep-alive.c
+++ b/src/nm-keep-alive.c
@@ -34,6 +34,8 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMKeepAlive,
);
typedef struct {
+ GObject *owner;
+
NMSettingsConnection *connection;
GDBusConnection *dbus_connection;
char *dbus_client;
@@ -398,6 +400,62 @@ get_property (GObject *object,
/*****************************************************************************/
+/**
+ * nm_keep_alive_get_owner:
+ * @self: the #NMKeepAlive
+ *
+ * Returns: the owner instance associated with this @self. This commonly
+ * is set to be the target instance, which @self guards for being alive.
+ * Returns a gpointer, but of course it's some GObject instance. */
+gpointer /* GObject * */
+nm_keep_alive_get_owner (NMKeepAlive *self)
+{
+ NMKeepAlivePrivate *priv = NM_KEEP_ALIVE_GET_PRIVATE (self);
+
+ nm_assert (!priv->owner || G_IS_OBJECT (priv->owner));
+
+ return priv->owner;
+}
+
+/**
+ * _nm_keep_alive_set_owner:
+ * @self: the #NMKeepAlive
+ * @owner: the owner to set or unset.
+ *
+ * Sets or unsets the owner instance. Think of the owner the target
+ * instance that is guarded by @self. It's the responsibility of the
+ * owner to set and properly unset this pointer. As the owner also
+ * controls the lifetime of the NMKeepAlive instance.
+ *
+ * This API is not to be called by everybody, but only the owner of
+ * @self.
+ */
+void
+_nm_keep_alive_set_owner (NMKeepAlive *self,
+ GObject *owner)
+{
+ NMKeepAlivePrivate *priv = NM_KEEP_ALIVE_GET_PRIVATE (self);
+
+ nm_assert (!owner || G_IS_OBJECT (owner));
+
+ /* it's bad style to reset the owner object. You are supposed to
+ * set it once, and clear it once. That's it. */
+ nm_assert (!owner || !priv->owner);
+
+ /* optimally, we would take a reference to @owner. But the
+ * owner already owns a refrence to the keep-alive, so we cannot
+ * just own a reference back.
+ *
+ * We could register a weak-pointer here. But instead, declare that
+ * owner is required to set itself as owner when creating the
+ * keep-alive instance, and unset itself when it lets go of the
+ * keep-alive instance (at latest, when the owner itself gets destroyed).
+ */
+ priv->owner = owner;
+}
+
+/*****************************************************************************/
+
static void
nm_keep_alive_init (NMKeepAlive *self)
{
@@ -419,6 +477,8 @@ dispose (GObject *object)
{
NMKeepAlive *self = NM_KEEP_ALIVE (object);
+ nm_assert (!NM_KEEP_ALIVE_GET_PRIVATE (self)->owner);
+
/* disarm also happens to free all resources. */
nm_keep_alive_disarm (self);
}
diff --git a/src/nm-keep-alive.h b/src/nm-keep-alive.h
index 3a7cd66858..72133224cd 100644
--- a/src/nm-keep-alive.h
+++ b/src/nm-keep-alive.h
@@ -53,4 +53,10 @@ void nm_keep_alive_set_dbus_client_watch (NMKeepAlive *self,
GDBusConnection *connection,
const char *client_address);
+gpointer /* GObject * */ nm_keep_alive_get_owner (NMKeepAlive *self);
+
+/* _nm_keep_alive_set_owner() is reserved for the owner to set/unset itself. */
+void _nm_keep_alive_set_owner (NMKeepAlive *self,
+ GObject *owner);
+
#endif /* __NETWORKMANAGER_KEEP_ALIVE_H__ */