core: define a full sort order for nm_settings_connection_cmp_timestamp()

We want to have some guaranteed order when comparing different connections.
So, in case of equal timestamps, proceed with comparing more properties.

It makes sense to consider the autoconnect-priority next.
This is what get_existing_connection() needs, thus we no longer
need to pre-sort the list.
This commit is contained in:
Thomas Haller 2017-02-05 20:05:57 +01:00
parent 93f7ab2c54
commit ef6c393889
2 changed files with 50 additions and 32 deletions

View file

@ -1749,7 +1749,7 @@ get_existing_connection (NMManager *self, NMDevice *device, gboolean *out_genera
/* 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);
cons = nm_manager_get_activatable_connections (self, &len, FALSE);
for (i = len; i > 0; )
connections = g_slist_prepend (connections, cons[--i]);
connections = g_slist_sort (connections, (GCompareFunc) nm_settings_connection_cmp_timestamp);

View file

@ -2162,29 +2162,64 @@ nm_settings_connection_set_flags_all (NMSettingsConnection *self, NMSettingsConn
/*****************************************************************************/
static int
_cmp_timestamp (NMSettingsConnection *a, NMSettingsConnection *b)
{
gboolean a_has_ts, b_has_ts;
guint64 ats = 0, bts = 0;
nm_assert (NM_IS_SETTINGS_CONNECTION (a));
nm_assert (NM_IS_SETTINGS_CONNECTION (b));
a_has_ts = !!nm_settings_connection_get_timestamp (a, &ats);
b_has_ts = !!nm_settings_connection_get_timestamp (b, &bts);
if (a_has_ts != b_has_ts)
return a_has_ts ? -1 : 1;
if (a_has_ts && ats != bts)
return (ats > bts) ? -1 : 1;
return 0;
}
static int
_cmp_last_resort (NMSettingsConnection *a, NMSettingsConnection *b)
{
int c;
nm_assert (NM_IS_SETTINGS_CONNECTION (a));
nm_assert (NM_IS_SETTINGS_CONNECTION (b));
c = g_strcmp0 (nm_connection_get_uuid (NM_CONNECTION (a)),
nm_connection_get_uuid (NM_CONNECTION (b)));
if (c)
return c;
/* hm, same UUID. Use their pointer value to give them a stable
* order. */
return (a > b) ? -1 : 1;
}
/* sorting for "best" connections.
* The function sorts connections in descending timestamp order.
* That means an older connection (lower timestamp) goes after
* a newer one.
*/
int
nm_settings_connection_cmp_timestamp (NMSettingsConnection *ac, NMSettingsConnection *bc)
nm_settings_connection_cmp_timestamp (NMSettingsConnection *a, NMSettingsConnection *b)
{
guint64 ats = 0, bts = 0;
int c;
if (ac == bc)
if (a == b)
return 0;
if (!ac)
if (!a)
return 1;
if (!bc)
if (!b)
return -1;
nm_settings_connection_get_timestamp (ac, &ats);
nm_settings_connection_get_timestamp (bc, &bts);
if (ats != bts)
return (ats > bts) ? -1 : 1;
return 0;
if ((c = _cmp_timestamp (a, b)))
return c;
if ((c = nm_utils_cmp_connection_by_autoconnect_priority (NM_CONNECTION (a), NM_CONNECTION (b))))
return c;
return _cmp_last_resort (a, b);
}
int
@ -2197,32 +2232,15 @@ nm_settings_connection_cmp_timestamp_p_with_data (gconstpointer pa, gconstpointe
int
nm_settings_connection_cmp_autoconnect_priority (NMSettingsConnection *a, NMSettingsConnection *b)
{
guint64 ats = 0, bts = 0;
int c;
if (a == b)
return 0;
/* first we compare them by their autoconnect priority. */
c = nm_utils_cmp_connection_by_autoconnect_priority (NM_CONNECTION (a), NM_CONNECTION (b));
if (c)
if ((c = nm_utils_cmp_connection_by_autoconnect_priority (NM_CONNECTION (a), NM_CONNECTION (b))))
return c;
/* then by their last activation timestamp (with the more recently connected one first) */
nm_settings_connection_get_timestamp (a, &ats);
nm_settings_connection_get_timestamp (b, &bts);
if (ats != bts)
return (ats > bts) ? -1 : 1;
/* if they are still equal, sort them by their UUID to give them an arbitrary, but stable
* order. */
c = g_strcmp0 (nm_connection_get_uuid (NM_CONNECTION (a)),
nm_connection_get_uuid (NM_CONNECTION (b)));
if (c)
if ((c = _cmp_timestamp (a, b)))
return c;
/* hm, still the same. Use their pointer value. */
return (a > b) ? -1 : 1;
return _cmp_last_resort (a, b);
}
int