From b3b1793f3dc4fcedb63fe51ecc9d3ed17aea6d35 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 3 Feb 2017 15:13:03 +0100 Subject: [PATCH] core: refactor nm_manager_get_activatable_connections() to return an array ... instead of a GSList. --- src/nm-manager.c | 57 ++++++++++++++++++++++++++++++------------------ src/nm-manager.h | 5 ++++- src/nm-policy.c | 34 +++++++++++++++++------------ 3 files changed, 60 insertions(+), 36 deletions(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index fef1f6b2d9..c06b5c4862 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -423,28 +423,34 @@ find_ac_for_connection (NMManager *manager, NMConnection *connection) return NULL; } +static gboolean +_get_activatable_connections_filter (NMSettings *settings, + NMSettingsConnection *connection, + gpointer user_data) +{ + return !find_ac_for_connection (user_data, NM_CONNECTION (connection)); +} + /* Filter out connections that are already active. * nm_settings_get_connections_sorted() returns sorted list. We need to preserve the * order so that we didn't change auto-activation order (recent timestamps * are first). * Caller is responsible for freeing the returned list with g_slist_free(). */ -GSList * -nm_manager_get_activatable_connections (NMManager *manager) +NMSettingsConnection ** +nm_manager_get_activatable_connections (NMManager *manager, guint *out_len, gboolean sort) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - gs_free NMSettingsConnection **all_connections = nm_settings_get_connections_sorted (priv->settings, NULL); - GSList *connections = NULL; - NMSettingsConnection *connection; - guint i; + NMSettingsConnection **connections; + guint len; - for (i = 0; all_connections[i]; i++) { - connection = all_connections[i]; - if (!find_ac_for_connection (manager, NM_CONNECTION (connection))) - connections = g_slist_prepend (connections, connection); - } - - return g_slist_reverse (connections); + connections = nm_settings_get_connections_clone (priv->settings, &len, + _get_activatable_connections_filter, + manager); + if (sort && len > 1) + g_qsort_with_data (connections, len, sizeof (connections[0]), nm_settings_connection_cmp_default_p_with_data, NULL); + NM_SET_OUT (out_len, len); + return connections; } static NMActiveConnection * @@ -1687,7 +1693,7 @@ static NMSettingsConnection * get_existing_connection (NMManager *self, NMDevice *device, gboolean *out_generated) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - gs_free_slist GSList *connections = nm_manager_get_activatable_connections (self); + gs_free_slist GSList *connections = NULL; NMConnection *connection = NULL; NMSettingsConnection *matched; NMSettingsConnection *added = NULL; @@ -1737,7 +1743,17 @@ get_existing_connection (NMManager *self, NMDevice *device, gboolean *out_genera * When no configured connection matches the generated connection, we keep * the generated connection instead. */ - connections = g_slist_sort (connections, (GCompareFunc) nm_settings_connection_cmp_timestamp); + { + gs_free NMSettingsConnection **cons = NULL; + guint i, len; + + /* XXX: this code will go away soon. Copy the array over to a GSList + * and don't bother for now. */ + cons = nm_manager_get_activatable_connections (self, &len, TRUE); + for (i = len; i > 0; ) + connections = g_slist_prepend (connections, cons[--i]); + connections = g_slist_sort (connections, (GCompareFunc) nm_settings_connection_cmp_timestamp); + } matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection (connections, connection, nm_device_has_carrier (device), @@ -2674,14 +2690,15 @@ ensure_master_active_connection (NMManager *self, * activate it on the device. */ if (master_state == NM_DEVICE_STATE_DISCONNECTED || !nm_device_is_real (master_device)) { - GSList *connections; + gs_free NMSettingsConnection **connections = NULL; + guint i; g_assert (master_connection == NULL); /* Find a compatible connection and activate this device using it */ - connections = nm_manager_get_activatable_connections (self); - for (iter = connections; iter; iter = g_slist_next (iter)) { - NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (iter->data); + connections = nm_manager_get_activatable_connections (self, NULL, TRUE); + for (i = 0; connections[i]; i++) { + NMSettingsConnection *candidate = connections[i]; /* Ensure eg bond/team slave and the candidate master is a * bond/team master @@ -2697,11 +2714,9 @@ ensure_master_active_connection (NMManager *self, master_device, subject, error); - g_slist_free (connections); return master_ac; } } - g_slist_free (connections); g_set_error (error, NM_MANAGER_ERROR, diff --git a/src/nm-manager.h b/src/nm-manager.h index c69fc9e192..a7baf30986 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -84,7 +84,10 @@ gboolean nm_manager_start (NMManager *manager, void nm_manager_stop (NMManager *manager); NMState nm_manager_get_state (NMManager *manager); const GSList *nm_manager_get_active_connections (NMManager *manager); -GSList * nm_manager_get_activatable_connections (NMManager *manager); + +NMSettingsConnection **nm_manager_get_activatable_connections (NMManager *manager, + guint *out_len, + gboolean sort); void nm_manager_write_device_state (NMManager *manager); diff --git a/src/nm-policy.c b/src/nm-policy.c index 92de1e38ec..0df576ffe2 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -953,6 +953,19 @@ activate_data_free (ActivateData *data) g_slice_free (ActivateData, data); } +static int +_auto_activate_device_cmp (gconstpointer pa, gconstpointer pb, gpointer user_data) +{ + NMSettingsConnection *a = NM_SETTINGS_CONNECTION (*((NMSettingsConnection **) pa)); + NMSettingsConnection *b = NM_SETTINGS_CONNECTION (*((NMSettingsConnection **) pb)); + int i; + + i = nm_utils_cmp_connection_by_autoconnect_priority (NM_CONNECTION (a), NM_CONNECTION (b)); + if (i != 0) + return i; + return nm_settings_connection_cmp_default (a, b); +} + static void auto_activate_device (NMPolicy *self, NMDevice *device) @@ -960,9 +973,8 @@ auto_activate_device (NMPolicy *self, NMPolicyPrivate *priv; NMSettingsConnection *best_connection; gs_free char *specific_object = NULL; - GPtrArray *connections; - GSList *connection_list; - guint i; + gs_free NMSettingsConnection **connections = NULL; + guint i, len; nm_assert (NM_IS_POLICY (self)); nm_assert (NM_IS_DEVICE (device)); @@ -976,21 +988,16 @@ auto_activate_device (NMPolicy *self, if (nm_device_get_act_request (device)) return; - connection_list = nm_manager_get_activatable_connections (priv->manager); - if (!connection_list) + connections = nm_manager_get_activatable_connections (priv->manager, &len, FALSE); + if (!connections[0]) return; - connections = _nm_utils_copy_slist_to_array (connection_list, NULL, NULL); - g_slist_free (connection_list); - - /* sort is stable (which is important at this point) so that connections - * with same priority are still sorted by last-connected-timestamp. */ - g_ptr_array_sort_with_data (connections, nm_utils_cmp_connection_by_autoconnect_priority_p_with_data, NULL); + g_qsort_with_data (connections, len, sizeof (connections[0]), _auto_activate_device_cmp, NULL); /* Find the first connection that should be auto-activated */ best_connection = NULL; - for (i = 0; i < connections->len; i++) { - NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (connections->pdata[i]); + for (i = 0; i < len; i++) { + NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (connections[i]); if (!nm_settings_connection_can_autoconnect (candidate)) continue; @@ -999,7 +1006,6 @@ auto_activate_device (NMPolicy *self, break; } } - g_ptr_array_free (connections, TRUE); if (best_connection) { GError *error = NULL;