diff options
author | Thomas Haller <thaller@redhat.com> | 2017-01-04 11:21:47 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2017-01-04 14:05:27 +0100 |
commit | 7c601ab8caa338f6d4803f595ebf4ffa90bd0726 (patch) | |
tree | 1969ab358eda052a7c1fc82e1a0284d4f2fb6e61 | |
parent | 674f5f24af90fe746e2f0465e7ade8b394d84d73 (diff) | |
download | NetworkManager-7c601ab8caa338f6d4803f595ebf4ffa90bd0726.tar.gz |
wifi: refactor getting sorted AP list
Instead of creating a GSList use an array. That way, we save
the allocation and free of an GSList instance. Also, avoid
cloning the export path. It is stable.
-rw-r--r-- | src/devices/wifi/nm-device-wifi.c | 110 |
1 files changed, 68 insertions, 42 deletions
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 5645ad3c7a..871c0d6547 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -997,66 +997,92 @@ can_auto_connect (NMDevice *device, return FALSE; } -static gint -ap_id_compare (NMWifiAP *a, NMWifiAP *b) +static int +ap_id_compare (gconstpointer p_a, gconstpointer p_b, gpointer user_data) { - guint32 a_id = nm_wifi_ap_get_id (a); - guint32 b_id = nm_wifi_ap_get_id (b); + guint32 a_id = nm_wifi_ap_get_id (*((NMWifiAP **) p_a)); + guint32 b_id = nm_wifi_ap_get_id (*((NMWifiAP **) p_b)); return a_id < b_id ? -1 : (a_id == b_id ? 0 : 1); } -static GSList * -get_sorted_ap_list (NMDeviceWifi *self) +static NMWifiAP ** +ap_list_get_sorted (NMDeviceWifi *self, gboolean include_without_ssid) { - GSList *sorted = NULL; + NMDeviceWifiPrivate *priv; + NMWifiAP **list; GHashTableIter iter; NMWifiAP *ap; + gsize i, n; - g_hash_table_iter_init (&iter, NM_DEVICE_WIFI_GET_PRIVATE (self)->aps); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) &ap)) - sorted = g_slist_prepend (sorted, ap); - return g_slist_sort (sorted, (GCompareFunc) ap_id_compare); + priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + + n = g_hash_table_size (priv->aps); + list = g_new (NMWifiAP *, n + 1); + + i = 0; + if (n > 0) { + g_hash_table_iter_init (&iter, priv->aps); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &ap)) { + nm_assert (i < n); + if ( include_without_ssid + || nm_wifi_ap_get_ssid (ap)) + list[i++] = ap; + } + nm_assert (i <= n); + nm_assert (!include_without_ssid || i == n); + + g_qsort_with_data (list, + i, + sizeof (gpointer), + ap_id_compare, + NULL); + } + list[i] = NULL; + return list; } -static void -impl_device_wifi_get_access_points (NMDeviceWifi *self, - GDBusMethodInvocation *context) +static const char ** +ap_list_get_sorted_paths (NMDeviceWifi *self, gboolean include_without_ssid) { - GSList *sorted, *iter; - GPtrArray *paths; + gpointer *list; + gsize i, j; - paths = g_ptr_array_new (); - sorted = get_sorted_ap_list (self); - for (iter = sorted; iter; iter = iter->next) { - NMWifiAP *ap = NM_WIFI_AP (iter->data); + list = (gpointer *) ap_list_get_sorted (self, include_without_ssid); + for (i = 0, j = 0; list[i]; i++) { + NMWifiAP *ap = list[i]; + const char *path; - if (nm_wifi_ap_get_ssid (ap)) - g_ptr_array_add (paths, g_strdup (nm_exported_object_get_path (NM_EXPORTED_OBJECT (ap)))); + /* update @list inplace to hold instead the export-path. */ + path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (ap)); + nm_assert (path); + list[j++] = (gpointer) path; } - g_ptr_array_add (paths, NULL); - g_slist_free (sorted); + return (const char **) list; +} + +static void +impl_device_wifi_get_access_points (NMDeviceWifi *self, + GDBusMethodInvocation *context) +{ + gs_free const char **list = NULL; + GVariant *v; - g_dbus_method_invocation_return_value (context, g_variant_new ("(^ao)", (char **) paths->pdata)); - g_ptr_array_unref (paths); + list = ap_list_get_sorted_paths (self, FALSE); + v = g_variant_new_objv (list, -1); + g_dbus_method_invocation_return_value (context, g_variant_new_tuple (&v, 1)); } static void impl_device_wifi_get_all_access_points (NMDeviceWifi *self, GDBusMethodInvocation *context) { - GSList *sorted, *iter; - GPtrArray *paths; - - paths = g_ptr_array_new (); - sorted = get_sorted_ap_list (self); - for (iter = sorted; iter; iter = iter->next) - g_ptr_array_add (paths, g_strdup (nm_exported_object_get_path (NM_EXPORTED_OBJECT (iter->data)))); - g_ptr_array_add (paths, NULL); - g_slist_free (sorted); + gs_free const char **list = NULL; + GVariant *v; - g_dbus_method_invocation_return_value (context, g_variant_new ("(^ao)", (char **) paths->pdata)); - g_ptr_array_unref (paths); + list = ap_list_get_sorted_paths (self, TRUE); + v = g_variant_new_objv (list, -1); + g_dbus_method_invocation_return_value (context, g_variant_new_tuple (&v, 1)); } static void @@ -1523,17 +1549,17 @@ ap_list_dump (gpointer user_data) { NMDeviceWifi *self = NM_DEVICE_WIFI (user_data); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - GSList *sorted, *iter; + gs_free NMWifiAP **list = NULL; + gsize i; priv->ap_dump_id = 0; _LOGD (LOGD_WIFI_SCAN, "APs: [now:%u last:%u next:%u]", nm_utils_get_monotonic_timestamp_s (), priv->last_scan, priv->scheduled_scan_time); - sorted = get_sorted_ap_list (self); - for (iter = sorted; iter; iter = iter->next) - nm_wifi_ap_dump (NM_WIFI_AP (iter->data), "dump ", nm_device_get_iface (NM_DEVICE (self))); - g_slist_free (sorted); + list = ap_list_get_sorted (self, TRUE); + for (i = 0; list[i]; i++) + nm_wifi_ap_dump (list[i], "dump ", nm_device_get_iface (NM_DEVICE (self))); return G_SOURCE_REMOVE; } |