diff options
Diffstat (limited to 'src/nm-active-connection.c')
| -rw-r--r-- | src/nm-active-connection.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c index f275b3ef..e9076136 100644 --- a/src/nm-active-connection.c +++ b/src/nm-active-connection.c @@ -59,6 +59,8 @@ typedef struct { NMActiveConnection *master; gboolean master_ready; + NMActiveConnection *parent; + gboolean assumed; NMAuthChain *chain; @@ -98,6 +100,7 @@ enum { enum { DEVICE_CHANGED, DEVICE_METERED_CHANGED, + PARENT_ACTIVE, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -678,6 +681,69 @@ nm_active_connection_get_assumed (NMActiveConnection *self) /****************************************************************/ +static void unwatch_parent (NMActiveConnection *self); + +static void +parent_destroyed (gpointer user_data, GObject *parent) +{ + NMActiveConnection *self = user_data; + + unwatch_parent (self); + g_signal_emit (self, signals[PARENT_ACTIVE], 0, NULL); +} + +static void +parent_state_cb (NMActiveConnection *parent_ac, + GParamSpec *pspec, + gpointer user_data) +{ + NMActiveConnection *self = user_data; + NMActiveConnectionState parent_state = nm_active_connection_get_state (parent_ac); + + if (parent_state < NM_ACTIVE_CONNECTION_STATE_ACTIVATED) + return; + + unwatch_parent (self); + g_signal_emit (self, signals[PARENT_ACTIVE], 0, parent_ac); +} + +static void +unwatch_parent (NMActiveConnection *self) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + + g_signal_handlers_disconnect_by_func (priv->parent, + (GCallback) parent_state_cb, + self); + g_object_weak_unref ((GObject *) priv->parent, parent_destroyed, self); + priv->parent = NULL; +} + +/** + * nm_active_connection_set_parent: + * @self: the #NMActiveConnection + * @parent: The #NMActiveConnection that must be active before the manager + * can proceed progressing the device to disconnected state for us. + * + * Sets the parent connection of @self. A "parent-active" signal will be + * emitted when the parent connection becomes active. + */ +void +nm_active_connection_set_parent (NMActiveConnection *self, NMActiveConnection *parent) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + + g_return_if_fail (priv->parent == NULL); + priv->parent = parent; + g_signal_connect (priv->parent, + "notify::" NM_ACTIVE_CONNECTION_STATE, + (GCallback) parent_state_cb, + self); + g_object_weak_ref ((GObject *) priv->parent, parent_destroyed, self); +} + +/****************************************************************/ + static void auth_done (NMAuthChain *chain, GError *error, @@ -1028,6 +1094,10 @@ dispose (GObject *object) self); } g_clear_object (&priv->master); + + if (priv->parent) + unwatch_parent (self); + g_clear_object (&priv->subject); G_OBJECT_CLASS (nm_active_connection_parent_class)->dispose (object); @@ -1208,6 +1278,14 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class) NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_UINT); + signals[PARENT_ACTIVE] = + g_signal_new (NM_ACTIVE_CONNECTION_PARENT_ACTIVE, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMActiveConnectionClass, parent_active), + NULL, NULL, NULL, + G_TYPE_NONE, 1, NM_TYPE_ACTIVE_CONNECTION); + nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (ac_class), NMDBUS_TYPE_ACTIVE_CONNECTION_SKELETON, NULL); |