summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-01-20 17:44:50 +0100
committerThomas Haller <thaller@redhat.com>2016-01-24 16:07:01 +0100
commit02ec76df5aaa3a3ad197cb1d53c0388029775b07 (patch)
tree0f919a2c21b5cad3c95a1b496ada5245e09833d4
parent9b3b94858bba189728932c85c826db2e5a6a8764 (diff)
downloadNetworkManager-02ec76df5aaa3a3ad197cb1d53c0388029775b07.tar.gz
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.
-rw-r--r--src/devices/nm-device.c110
1 files changed, 64 insertions, 46 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 010c7fe99c..84b50451e7 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -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);
+ g_object_notify ((GObject *) self, NM_DEVICE_AVAILABLE_CONNECTIONS);
}
-static void
-available_connections_del_all (NMDevice *self, gboolean do_signal)
+static gboolean
+available_connections_del_all (NMDevice *self)
{
- g_hash_table_remove_all (NM_DEVICE_GET_PRIVATE (self)->available_connections);
- if (do_signal == TRUE)
- available_connections_notify (self);
+ 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
-available_connections_update (NMDevice *self, NMConnection *connection)
+available_connections_add (NMDevice *self, NMConnection *connection)
{
- 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;
+ return nm_g_hash_table_add (self->priv->available_connections, g_object_ref (connection));
}
static gboolean
-_del_available_connection (NMDevice *self, NMConnection *connection)
+available_connections_del (NMDevice *self, NMConnection *connection)
{
- return g_hash_table_remove (NM_DEVICE_GET_PRIVATE (self)->available_connections, 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,43 +9425,36 @@ 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))
- available_connections_notify (self);
-}
-
-static void
-cp_connection_removed (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
-{
- NMDevice *self = user_data;
-
- g_return_if_fail (NM_IS_DEVICE (self));
+ 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 (_del_available_connection (self, connection)) {
+ if (changed) {
available_connections_notify (self);
available_connections_check_delete_unrealized (self);
}
}
static void
-cp_connection_updated (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
+cp_connection_removed (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);