device: cleanup handling available-connections

For update, don't delete first and add it again. Just do it
in one step.

For recheck, don't delete all connections first to add them
all anew. Instead, check what changes and only emit the changed
signal if there are any actual changes.
This commit is contained in:
Thomas Haller 2016-01-20 17:44:50 +01:00
parent 9b3b94858b
commit 02ec76df5a

View file

@ -9285,32 +9285,28 @@ nm_device_check_connection_available (NMDevice *self,
static void
available_connections_notify (NMDevice *self)
{
g_object_notify (G_OBJECT (self), NM_DEVICE_AVAILABLE_CONNECTIONS);
}
static void
available_connections_del_all (NMDevice *self, gboolean do_signal)
{
g_hash_table_remove_all (NM_DEVICE_GET_PRIVATE (self)->available_connections);
if (do_signal == TRUE)
available_connections_notify (self);
g_object_notify ((GObject *) self, NM_DEVICE_AVAILABLE_CONNECTIONS);
}
static gboolean
available_connections_update (NMDevice *self, NMConnection *connection)
available_connections_del_all (NMDevice *self)
{
if (nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_NONE, NULL)) {
g_hash_table_add (NM_DEVICE_GET_PRIVATE (self)->available_connections,
g_object_ref (connection));
return TRUE;
}
return FALSE;
if (g_hash_table_size (self->priv->available_connections) == 0)
return FALSE;
g_hash_table_remove_all (self->priv->available_connections);
return TRUE;
}
static gboolean
_del_available_connection (NMDevice *self, NMConnection *connection)
available_connections_add (NMDevice *self, NMConnection *connection)
{
return g_hash_table_remove (NM_DEVICE_GET_PRIVATE (self)->available_connections, connection);
return nm_g_hash_table_add (self->priv->available_connections, g_object_ref (connection));
}
static gboolean
available_connections_del (NMDevice *self, NMConnection *connection)
{
return g_hash_table_remove (self->priv->available_connections, connection);
}
static gboolean
@ -9345,22 +9341,51 @@ nm_device_recheck_available_connections (NMDevice *self)
{
NMDevicePrivate *priv;
const GSList *connections, *iter;
gboolean changed = FALSE;
GHashTableIter h_iter;
NMConnection *connection;
g_return_if_fail (NM_IS_DEVICE (self));
priv = NM_DEVICE_GET_PRIVATE(self);
if (priv->con_provider) {
available_connections_del_all (self, FALSE);
gs_unref_hashtable GHashTable *prune_list = NULL;
if (g_hash_table_size (priv->available_connections) > 0) {
prune_list = g_hash_table_new (g_direct_hash, g_direct_equal);
g_hash_table_iter_init (&h_iter, priv->available_connections);
while (g_hash_table_iter_next (&h_iter, (gpointer *) &connection, NULL))
g_hash_table_add (prune_list, connection);
}
connections = nm_connection_provider_get_connections (priv->con_provider);
for (iter = connections; iter; iter = g_slist_next (iter))
available_connections_update (self, NM_CONNECTION (iter->data));
for (iter = connections; iter; iter = g_slist_next (iter)) {
connection = NM_CONNECTION (iter->data);
available_connections_notify (self);
if (available_connections_add (self, connection)) {
if (prune_list)
g_hash_table_remove (prune_list, connection);
changed = TRUE;
}
}
if (prune_list) {
g_hash_table_iter_init (&h_iter, prune_list);
while (g_hash_table_iter_next (&h_iter, (gpointer *) &connection, NULL)) {
if (available_connections_del (self, connection))
changed = TRUE;
}
}
} else {
if (available_connections_del_all (self))
changed = TRUE;
}
available_connections_check_delete_unrealized (self);
if (changed) {
available_connections_notify (self);
available_connections_check_delete_unrealized (self);
}
}
/**
@ -9400,14 +9425,26 @@ nm_device_get_available_connections (NMDevice *self, const char *specific_object
}
static void
cp_connection_added (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
cp_connection_added_or_updated (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
{
gboolean changed;
NMDevice *self = user_data;
g_return_if_fail (NM_IS_DEVICE (self));
g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection));
if (available_connections_update (self, connection))
if (nm_device_check_connection_available (self,
connection,
NM_DEVICE_CHECK_CON_AVAILABLE_NONE,
NULL))
changed = available_connections_add (self, connection);
else
changed = available_connections_del (self, connection);
if (changed) {
available_connections_notify (self);
available_connections_check_delete_unrealized (self);
}
}
static void
@ -9417,26 +9454,7 @@ cp_connection_removed (NMConnectionProvider *cp, NMConnection *connection, gpoin
g_return_if_fail (NM_IS_DEVICE (self));
if (_del_available_connection (self, connection)) {
available_connections_notify (self);
available_connections_check_delete_unrealized (self);
}
}
static void
cp_connection_updated (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
{
NMDevice *self = user_data;
gboolean added, deleted;
g_return_if_fail (NM_IS_DEVICE (self));
/* FIXME: don't remove it from the hash if it's just going to get re-added */
deleted = _del_available_connection (self, connection);
added = available_connections_update (self, connection);
/* Only signal if the connection was removed OR added, but not both */
if (added != deleted) {
if (available_connections_del (self, connection)) {
available_connections_notify (self);
available_connections_check_delete_unrealized (self);
}
@ -10058,7 +10076,8 @@ _set_state_full (NMDevice *self,
req = priv->act_request ? g_object_ref (priv->act_request) : NULL;
if (state <= NM_DEVICE_STATE_UNAVAILABLE) {
available_connections_del_all (self, TRUE);
if (available_connections_del_all (self))
available_connections_notify (self);
_clear_queued_act_request (priv);
}
@ -10746,7 +10765,7 @@ constructed (GObject *object)
g_assert (priv->con_provider);
g_signal_connect (priv->con_provider,
NM_CP_SIGNAL_CONNECTION_ADDED,
G_CALLBACK (cp_connection_added),
G_CALLBACK (cp_connection_added_or_updated),
self);
g_signal_connect (priv->con_provider,
@ -10756,7 +10775,7 @@ constructed (GObject *object)
g_signal_connect (priv->con_provider,
NM_CP_SIGNAL_CONNECTION_UPDATED,
G_CALLBACK (cp_connection_updated),
G_CALLBACK (cp_connection_added_or_updated),
self);
/* Update default-unmanaged device available connections immediately,
@ -10811,13 +10830,12 @@ dispose (GObject *object)
link_disconnect_action_cancel (self);
if (priv->con_provider) {
g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_added, self);
g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_added_or_updated, self);
g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_removed, self);
g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_updated, self);
priv->con_provider = NULL;
}
g_hash_table_remove_all (priv->available_connections);
available_connections_del_all (self);
nm_clear_g_source (&priv->carrier_wait_id);