<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40367 >

 It's possible that city starves out of existence while they are
iterated. Attached patch adds city_list_iterate_safe() to fix problems
that might cause.

 This code was part of unit_lost events in #34717.


 - ML

diff -Nurd -X.diff_ignore freeciv/common/city.h freeciv/common/city.h
--- freeciv/common/city.h       2008-05-13 13:25:13.000000000 +0300
+++ freeciv/common/city.h       2008-07-08 17:08:26.000000000 +0300
@@ -423,6 +423,33 @@
   } players_iterate_end;                                                    \
 }
 
+#define city_list_iterate_safe(citylist, _city)                        \
+{                                                                      \
+  int _city##_size = city_list_size(citylist);                         \
+                                                                       \
+  if (_city##_size > 0) {                                              \
+    int _city##_numbers[_city##_size];                                 \
+    int _city##_index = 0;                                             \
+                                                                       \
+    city_list_iterate(citylist, _city) {                               \
+      _city##_numbers[_city##_index++] = _city->id;                    \
+    } city_list_iterate_end;                                           \
+                                                                       \
+    for (_city##_index = 0;                                            \
+        _city##_index < _city##_size;                                  \
+        _city##_index++) {                                             \
+      struct city *_city =                                             \
+       game_find_city_by_number(_city##_numbers[_city##_index]);       \
+                                                                       \
+      if (NULL != _city) {
+
+#define city_list_iterate_safe_end                                     \
+      }                                                                \
+    }                                                                  \
+  }                                                                    \
+}
+
+
 
 /* output type functions */
 
diff -Nurd -X.diff_ignore freeciv/server/cityturn.c freeciv/server/cityturn.c
--- freeciv/server/cityturn.c   2008-07-03 21:58:06.000000000 +0300
+++ freeciv/server/cityturn.c   2008-07-08 17:09:12.000000000 +0300
@@ -418,9 +418,9 @@
   int gold;
   gold=pplayer->economic.gold;
   pplayer->bulbs_last_turn = 0;
-  city_list_iterate(pplayer->cities, pcity)
+  city_list_iterate_safe(pplayer->cities, pcity)
      update_city_activity(pplayer, pcity);
-  city_list_iterate_end;
+  city_list_iterate_safe_end;
   pplayer->ai.prev_gold = gold;
   /* This test include the cost of the units because pay_for_units is called
    * in update_city_activity */
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to