Merge lp:~dshea/timezonemap/location-cycle into lp:timezonemap

Proposed by David Shea
Status: Merged
Merged at revision: 51
Proposed branch: lp:~dshea/timezonemap/location-cycle
Merge into: lp:timezonemap
Diff against target: 76 lines (+35/-7)
1 file modified
src/cc-timezone-map.c (+35/-7)
To merge this branch: bzr merge lp:~dshea/timezonemap/location-cycle
Reviewer Review Type Date Requested Status
Iain Lane Approve
Review via email: mp+254831@code.launchpad.net

Description of the change

An anaconda user noticed (https://bugzilla.redhat.com/show_bug.cgi?id=1190265) that if you repeatedly click the same spot on the map, it will choose different locations for each click (which is intentional), to the point where clicks will start jumping wildly across the map as the search area expands outwards (which is probably less intentional). While looking into this, I found that the handling of the repeated clicks resulted in a memory leak in priv->distances, and if you managed to get to the end of the list it would crash. The first patch addresses the memory problems, and the second limits the location search to a 50px radius.

To post a comment you must log in.
Revision history for this message
Adam Williamson (awilliamson) wrote :

Aw, no is_canada() ? :P

Revision history for this message
Iain Lane (laney) wrote :

Cool, thanks

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/cc-timezone-map.c'
--- src/cc-timezone-map.c 2013-12-16 17:27:20 +0000
+++ src/cc-timezone-map.c 2015-03-31 20:04:30 +0000
@@ -68,6 +68,8 @@
68 CcTimezoneLocation *location;68 CcTimezoneLocation *location;
69 GHashTable *alias_db;69 GHashTable *alias_db;
70 GList *distances;70 GList *distances;
71 /* Store the head of the list separately so it can be freed later */
72 GList *distances_head;
7173
72 gint previous_x;74 gint previous_x;
73 gint previous_y;75 gint previous_y;
@@ -594,9 +596,10 @@
594 g_hash_table_destroy (priv->alias_db);596 g_hash_table_destroy (priv->alias_db);
595 priv->alias_db = NULL;597 priv->alias_db = NULL;
596 }598 }
597 if (priv->distances)599 if (priv->distances_head)
598 {600 {
599 g_list_free (priv->distances);601 g_list_free (priv->distances_head);
602 priv->distances_head = NULL;
600 priv->distances = NULL;603 priv->distances = NULL;
601 }604 }
602605
@@ -991,10 +994,15 @@
991 if (x == priv->previous_x && y == priv->previous_y) 994 if (x == priv->previous_x && y == priv->previous_y)
992 {995 {
993 priv->distances = g_list_next (priv->distances);996 priv->distances = g_list_next (priv->distances);
997 if (!priv->distances)
998 priv->distances = priv->distances_head;
999
994 location = (CcTimezoneLocation*) priv->distances->data;1000 location = (CcTimezoneLocation*) priv->distances->data;
995 } else {1001 } else {
996 g_list_free (priv->distances);1002 GList *node;
997 priv->distances = NULL;1003
1004 g_list_free (priv->distances_head);
1005 priv->distances_head = NULL;
998 for (i = 0; i < array->len; i++)1006 for (i = 0; i < array->len; i++)
999 {1007 {
1000 gdouble pointx, pointy, dx, dy;1008 gdouble pointx, pointy, dx, dy;
@@ -1007,9 +1015,29 @@
1007 dy = pointy - y;1015 dy = pointy - y;
10081016
1009 cc_timezone_location_set_dist(loc, (gdouble) dx * dx + dy * dy);1017 cc_timezone_location_set_dist(loc, (gdouble) dx * dx + dy * dy);
1010 priv->distances = g_list_prepend (priv->distances, loc);1018 priv->distances_head = g_list_prepend (priv->distances_head, loc);
1011 }1019 }
1012 priv->distances = g_list_sort (priv->distances, (GCompareFunc) sort_locations);1020 priv->distances_head = g_list_sort (priv->distances_head, (GCompareFunc) sort_locations);
1021
1022 /* Remove locations from the list with a distance of greater than 50px,
1023 * so that repeated clicks cycle through a smaller area instead of
1024 * jumping all over the map. Start with the second element to ensure
1025 * that at least one element stays in the list.
1026 */
1027 node = priv->distances_head->next;
1028 while (node != NULL)
1029 {
1030 if (cc_timezone_location_get_dist(node->data) > (50 * 50))
1031 {
1032 /* Cut the list off here */
1033 node->prev->next = NULL;
1034 g_list_free(node);
1035 }
1036
1037 node = g_list_next(node);
1038 }
1039
1040 priv->distances = priv->distances_head;
1013 location = (CcTimezoneLocation*) priv->distances->data;1041 location = (CcTimezoneLocation*) priv->distances->data;
1014 priv->previous_x = x;1042 priv->previous_x = x;
1015 priv->previous_y = y;1043 priv->previous_y = y;

Subscribers

People subscribed via source and target branches

to all changes: