active-connection: add parent active connection tracking

Make it possible to let active connection know about an active
connection it depends on and emit a signal when the parent is active.
This commit is contained in:
Lubomir Rintel
2016-03-23 14:47:02 +01:00
parent ce745e098a
commit 6e382ea91d
2 changed files with 84 additions and 0 deletions

View File

@@ -59,6 +59,8 @@ typedef struct {
NMActiveConnection *master; NMActiveConnection *master;
gboolean master_ready; gboolean master_ready;
NMActiveConnection *parent;
gboolean assumed; gboolean assumed;
NMAuthChain *chain; NMAuthChain *chain;
@@ -98,6 +100,7 @@ enum {
enum { enum {
DEVICE_CHANGED, DEVICE_CHANGED,
DEVICE_METERED_CHANGED, DEVICE_METERED_CHANGED,
PARENT_ACTIVE,
LAST_SIGNAL LAST_SIGNAL
}; };
static guint signals[LAST_SIGNAL] = { 0 }; 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 static void
auth_done (NMAuthChain *chain, auth_done (NMAuthChain *chain,
GError *error, GError *error,
@@ -1028,6 +1094,10 @@ dispose (GObject *object)
self); self);
} }
g_clear_object (&priv->master); g_clear_object (&priv->master);
if (priv->parent)
unwatch_parent (self);
g_clear_object (&priv->subject); g_clear_object (&priv->subject);
G_OBJECT_CLASS (nm_active_connection_parent_class)->dispose (object); 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, NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_UINT); 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), nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (ac_class),
NMDBUS_TYPE_ACTIVE_CONNECTION_SKELETON, NMDBUS_TYPE_ACTIVE_CONNECTION_SKELETON,
NULL); NULL);

View File

@@ -58,6 +58,7 @@
/* Internal signals*/ /* Internal signals*/
#define NM_ACTIVE_CONNECTION_DEVICE_CHANGED "device-changed" #define NM_ACTIVE_CONNECTION_DEVICE_CHANGED "device-changed"
#define NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED "device-metered-changed" #define NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED "device-metered-changed"
#define NM_ACTIVE_CONNECTION_PARENT_ACTIVE "parent-active"
struct _NMActiveConnection { struct _NMActiveConnection {
NMExportedObject parent; NMExportedObject parent;
@@ -81,6 +82,8 @@ typedef struct {
void (*device_metered_changed) (NMActiveConnection *connection, void (*device_metered_changed) (NMActiveConnection *connection,
NMMetered new_value); NMMetered new_value);
void (*parent_active) (NMActiveConnection *connection);
} NMActiveConnectionClass; } NMActiveConnectionClass;
guint64 nm_active_connection_version_id_get (NMActiveConnection *self); guint64 nm_active_connection_version_id_get (NMActiveConnection *self);
@@ -148,6 +151,9 @@ gboolean nm_active_connection_get_master_ready (NMActiveConnection *self);
void nm_active_connection_set_master (NMActiveConnection *self, void nm_active_connection_set_master (NMActiveConnection *self,
NMActiveConnection *master); NMActiveConnection *master);
void nm_active_connection_set_parent (NMActiveConnection *self,
NMActiveConnection *parent);
void nm_active_connection_set_assumed (NMActiveConnection *self, void nm_active_connection_set_assumed (NMActiveConnection *self,
gboolean assumed); gboolean assumed);