diff options
author | Thomas Haller <thaller@redhat.com> | 2016-01-20 17:44:50 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2016-01-24 16:07:01 +0100 |
commit | 02ec76df5aaa3a3ad197cb1d53c0388029775b07 (patch) | |
tree | 0f919a2c21b5cad3c95a1b496ada5245e09833d4 /src | |
parent | 9b3b94858bba189728932c85c826db2e5a6a8764 (diff) | |
download | NetworkManager-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.
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/nm-device.c | 110 |
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); |